1963051aaSJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 2963051aaSJerome Forissier /* 3963051aaSJerome Forissier * Copyright (c) 2014, STMicroelectronics International N.V. 4963051aaSJerome Forissier */ 5963051aaSJerome Forissier 6963051aaSJerome Forissier #include <compiler.h> 7963051aaSJerome Forissier #include <kernel/panic.h> 800b3b9a2SJens Wiklander #include <kernel/pseudo_ta.h> 900b3b9a2SJens Wiklander #include <kernel/tee_ta_manager.h> 1000b3b9a2SJens Wiklander #include <kernel/ts_manager.h> 11963051aaSJerome Forissier #include <mm/core_memprot.h> 12963051aaSJerome Forissier #include <pta_invoke_tests.h> 13963051aaSJerome Forissier #include <string.h> 14963051aaSJerome Forissier #include <tee_api_defines.h> 15963051aaSJerome Forissier #include <tee_api_types.h> 1600b3b9a2SJens Wiklander #include <tee/cache.h> 17963051aaSJerome Forissier #include <trace.h> 18963051aaSJerome Forissier #include <types_ext.h> 19963051aaSJerome Forissier 20963051aaSJerome Forissier #include "misc.h" 21963051aaSJerome Forissier 22963051aaSJerome Forissier #define TA_NAME "invoke_tests.pta" 23963051aaSJerome Forissier 24963051aaSJerome Forissier static TEE_Result test_trace(uint32_t param_types __unused, 25963051aaSJerome Forissier TEE_Param params[TEE_NUM_PARAMS] __unused) 26963051aaSJerome Forissier { 27963051aaSJerome Forissier IMSG("pseudo TA \"%s\" says \"Hello world !\"", TA_NAME); 28963051aaSJerome Forissier 29963051aaSJerome Forissier return TEE_SUCCESS; 30963051aaSJerome Forissier } 31963051aaSJerome Forissier 32c2e4eb43SAnton Rybakov static int test_v2p2v(void *va, size_t size) 33963051aaSJerome Forissier { 3400b3b9a2SJens Wiklander struct ts_session *session = NULL; 3500b3b9a2SJens Wiklander paddr_t p = 0; 3600b3b9a2SJens Wiklander void *v = NULL; 37963051aaSJerome Forissier 38963051aaSJerome Forissier if (!va) 39963051aaSJerome Forissier return 0; 40963051aaSJerome Forissier 4100b3b9a2SJens Wiklander session = ts_get_current_session(); 42963051aaSJerome Forissier p = virt_to_phys(va); 43963051aaSJerome Forissier 44963051aaSJerome Forissier /* 0 is not a valid physical address */ 45963051aaSJerome Forissier if (!p) 46963051aaSJerome Forissier return 1; 47963051aaSJerome Forissier 4800b3b9a2SJens Wiklander if (to_ta_session(session)->clnt_id.login == TEE_LOGIN_TRUSTED_APP) { 49c2e4eb43SAnton Rybakov v = phys_to_virt(p, MEM_AREA_TS_VASPACE, size); 50963051aaSJerome Forissier } else { 51c2e4eb43SAnton Rybakov v = phys_to_virt(p, MEM_AREA_NSEC_SHM, size); 52963051aaSJerome Forissier if (!v) 53c2e4eb43SAnton Rybakov v = phys_to_virt(p, MEM_AREA_SDP_MEM, size); 54963051aaSJerome Forissier if (!v) 55c2e4eb43SAnton Rybakov v = phys_to_virt(p, MEM_AREA_SHM_VASPACE, size); 56963051aaSJerome Forissier } 57963051aaSJerome Forissier 58963051aaSJerome Forissier /* 59963051aaSJerome Forissier * Return an error only the vaddr found mismatches input address. 60963051aaSJerome Forissier * Finding a virtual address from a physical address cannot be painful 61963051aaSJerome Forissier * in some case (i.e pager). Moreover this operation is more debug 62963051aaSJerome Forissier * related. Thus do not report error if phys_to_virt failed 63963051aaSJerome Forissier */ 64963051aaSJerome Forissier if (v && va != v) { 65963051aaSJerome Forissier EMSG("Failed to p2v/v2p on caller TA memref arguments"); 66963051aaSJerome Forissier EMSG("va %p -> pa 0x%" PRIxPA " -> va %p", va, p, v); 67963051aaSJerome Forissier return 1; 68963051aaSJerome Forissier } 69963051aaSJerome Forissier 70963051aaSJerome Forissier return 0; 71963051aaSJerome Forissier } 72963051aaSJerome Forissier 73963051aaSJerome Forissier /* 74b213d8bdSEtienne Carriere * Check PTA can be invoked with a memory reference on a NULL buffer 75b213d8bdSEtienne Carriere */ 76b213d8bdSEtienne Carriere static TEE_Result test_entry_memref_null(uint32_t type, 77b213d8bdSEtienne Carriere TEE_Param p[TEE_NUM_PARAMS]) 78b213d8bdSEtienne Carriere { 79b213d8bdSEtienne Carriere uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 80b213d8bdSEtienne Carriere TEE_PARAM_TYPE_NONE, 81b213d8bdSEtienne Carriere TEE_PARAM_TYPE_NONE, 82b213d8bdSEtienne Carriere TEE_PARAM_TYPE_NONE); 83b213d8bdSEtienne Carriere 84b213d8bdSEtienne Carriere if (exp_pt != type) 85b213d8bdSEtienne Carriere return TEE_ERROR_BAD_PARAMETERS; 86b213d8bdSEtienne Carriere 87b213d8bdSEtienne Carriere if (p[0].memref.buffer || p[0].memref.size) 88b213d8bdSEtienne Carriere return TEE_ERROR_BAD_PARAMETERS; 89b213d8bdSEtienne Carriere 90b213d8bdSEtienne Carriere return TEE_SUCCESS; 91b213d8bdSEtienne Carriere } 92b213d8bdSEtienne Carriere 93b213d8bdSEtienne Carriere /* 94963051aaSJerome Forissier * Supported tests on parameters 95963051aaSJerome Forissier * (I, J, K, L refer to param index) 96963051aaSJerome Forissier * 97963051aaSJerome Forissier * Case 1: command parameters type are: 1 in/out value, 3 empty. 98963051aaSJerome Forissier * => process outI.a = inI.a + inI.b 99963051aaSJerome Forissier * Case 2: command parameters type are: 3 input value, 1 output value 100963051aaSJerome Forissier * => process = outI.a = inJ.a + inK.a + inL.a 101963051aaSJerome Forissier * Case 3: command parameters type are: 1 in/out memref, 3 empty. 102963051aaSJerome Forissier * => process = outI[0] = sum(inI[0..len-1]) 103963051aaSJerome Forissier */ 104963051aaSJerome Forissier static TEE_Result test_entry_params(uint32_t type, TEE_Param p[TEE_NUM_PARAMS]) 105963051aaSJerome Forissier { 106963051aaSJerome Forissier size_t i; 107963051aaSJerome Forissier uint8_t d8, *in; 108963051aaSJerome Forissier 109963051aaSJerome Forissier /* case 1a: 1 input/output value argument */ 110963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INOUT) && 111963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) && 112963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) && 113963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) { 114963051aaSJerome Forissier p[0].value.a = p[0].value.a + p[0].value.b; 115963051aaSJerome Forissier return TEE_SUCCESS; 116963051aaSJerome Forissier } 117963051aaSJerome Forissier /* case 1b: 1 input/output value argument */ 118963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) && 119963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INOUT) && 120963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) && 121963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) { 122963051aaSJerome Forissier p[1].value.a = p[1].value.a + p[1].value.b; 123963051aaSJerome Forissier return TEE_SUCCESS; 124963051aaSJerome Forissier } 125963051aaSJerome Forissier /* case 1c: 1 input/output value argument */ 126963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) && 127963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) && 128963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INOUT) && 129963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) { 130963051aaSJerome Forissier p[2].value.a = p[2].value.a + p[2].value.b; 131963051aaSJerome Forissier return TEE_SUCCESS; 132963051aaSJerome Forissier } 133963051aaSJerome Forissier /* case 1d: 1 input/output value argument */ 134963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) && 135963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) && 136963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) && 137963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INOUT)) { 138963051aaSJerome Forissier p[3].value.a = p[3].value.a + p[3].value.b; 139963051aaSJerome Forissier return TEE_SUCCESS; 140963051aaSJerome Forissier } 141963051aaSJerome Forissier 142963051aaSJerome Forissier /* case 2a: 3 input value arguments, 1 output value argument */ 143963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_OUTPUT) && 144963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) && 145963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) && 146963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) { 147963051aaSJerome Forissier p[0].value.a = p[1].value.a + p[2].value.a + p[3].value.a; 148963051aaSJerome Forissier p[0].value.b = p[1].value.b + p[2].value.b + p[3].value.b; 149963051aaSJerome Forissier return TEE_SUCCESS; 150963051aaSJerome Forissier } 151963051aaSJerome Forissier /* case 2a: 3 input value arguments, 1 output value argument */ 152963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) && 153963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_OUTPUT) && 154963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) && 155963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) { 156963051aaSJerome Forissier p[1].value.a = p[0].value.a + p[2].value.a + p[3].value.a; 157963051aaSJerome Forissier p[1].value.b = p[0].value.b + p[2].value.b + p[3].value.b; 158963051aaSJerome Forissier return TEE_SUCCESS; 159963051aaSJerome Forissier } 160963051aaSJerome Forissier /* case 2a: 3 input value arguments, 1 output value argument */ 161963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) && 162963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) && 163963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_OUTPUT) && 164963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_INPUT)) { 165963051aaSJerome Forissier p[2].value.a = p[0].value.a + p[1].value.a + p[3].value.a; 166963051aaSJerome Forissier p[2].value.b = p[0].value.b + p[1].value.b + p[3].value.b; 167963051aaSJerome Forissier return TEE_SUCCESS; 168963051aaSJerome Forissier } 169963051aaSJerome Forissier /* case 2a: 3 input value arguments, 1 output value argument */ 170963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_VALUE_INPUT) && 171963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_VALUE_INPUT) && 172963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_VALUE_INPUT) && 173963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_VALUE_OUTPUT)) { 174963051aaSJerome Forissier p[3].value.a = p[0].value.a + p[1].value.a + p[2].value.a; 175963051aaSJerome Forissier p[3].value.b = p[0].value.b + p[1].value.b + p[2].value.b; 176963051aaSJerome Forissier return TEE_SUCCESS; 177963051aaSJerome Forissier } 178963051aaSJerome Forissier 179*7509620bSJens Wiklander DMSG("expect memref params: %p/%zu - %p/%zu - %p/%zu - %p/%zu", 180*7509620bSJens Wiklander p[0].memref.buffer, p[0].memref.size, p[1].memref.buffer, 181*7509620bSJens Wiklander p[1].memref.size, p[2].memref.buffer, p[2].memref.size, 182963051aaSJerome Forissier p[3].memref.buffer, p[3].memref.size); 183963051aaSJerome Forissier 184963051aaSJerome Forissier /* case 3a: 1 in/out memref argument */ 185963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_MEMREF_INOUT) && 186963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) && 187963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) && 188963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) { 189963051aaSJerome Forissier in = (uint8_t *)p[0].memref.buffer; 190c2e4eb43SAnton Rybakov if (test_v2p2v(in, p[0].memref.size)) 191963051aaSJerome Forissier return TEE_ERROR_SECURITY; 192963051aaSJerome Forissier d8 = 0; 193963051aaSJerome Forissier for (i = 0; i < p[0].memref.size; i++) 194963051aaSJerome Forissier d8 += in[i]; 195963051aaSJerome Forissier *(uint8_t *)p[0].memref.buffer = d8; 196963051aaSJerome Forissier return TEE_SUCCESS; 197963051aaSJerome Forissier } 198963051aaSJerome Forissier /* case 3b: 1 in/out memref argument */ 199963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) && 200963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_MEMREF_INOUT) && 201963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) && 202963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) { 203963051aaSJerome Forissier in = (uint8_t *)p[1].memref.buffer; 204c2e4eb43SAnton Rybakov if (test_v2p2v(in, p[1].memref.size)) 205963051aaSJerome Forissier return TEE_ERROR_SECURITY; 206963051aaSJerome Forissier d8 = 0; 207963051aaSJerome Forissier for (i = 0; i < p[1].memref.size; i++) 208963051aaSJerome Forissier d8 += in[i]; 209963051aaSJerome Forissier *(uint8_t *)p[1].memref.buffer = d8; 210963051aaSJerome Forissier return TEE_SUCCESS; 211963051aaSJerome Forissier } 212963051aaSJerome Forissier /* case 3c: 1 in/out memref argument */ 213963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) && 214963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) && 215963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_MEMREF_INOUT) && 216963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_NONE)) { 217963051aaSJerome Forissier in = (uint8_t *)p[2].memref.buffer; 218c2e4eb43SAnton Rybakov if (test_v2p2v(in, p[2].memref.size)) 219963051aaSJerome Forissier return TEE_ERROR_SECURITY; 220963051aaSJerome Forissier d8 = 0; 221963051aaSJerome Forissier for (i = 0; i < p[2].memref.size; i++) 222963051aaSJerome Forissier d8 += in[i]; 223963051aaSJerome Forissier *(uint8_t *)p[2].memref.buffer = d8; 224963051aaSJerome Forissier return TEE_SUCCESS; 225963051aaSJerome Forissier } 226963051aaSJerome Forissier /* case 3d: 1 in/out memref argument */ 227963051aaSJerome Forissier if ((TEE_PARAM_TYPE_GET(type, 0) == TEE_PARAM_TYPE_NONE) && 228963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 1) == TEE_PARAM_TYPE_NONE) && 229963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 2) == TEE_PARAM_TYPE_NONE) && 230963051aaSJerome Forissier (TEE_PARAM_TYPE_GET(type, 3) == TEE_PARAM_TYPE_MEMREF_INOUT)) { 231963051aaSJerome Forissier in = (uint8_t *)p[3].memref.buffer; 232c2e4eb43SAnton Rybakov if (test_v2p2v(in, p[3].memref.size)) 233963051aaSJerome Forissier return TEE_ERROR_SECURITY; 234963051aaSJerome Forissier d8 = 0; 235963051aaSJerome Forissier for (i = 0; i < p[3].memref.size; i++) 236963051aaSJerome Forissier d8 += in[i]; 237963051aaSJerome Forissier *(uint8_t *)p[3].memref.buffer = d8; 238963051aaSJerome Forissier return TEE_SUCCESS; 239963051aaSJerome Forissier } 240963051aaSJerome Forissier 241963051aaSJerome Forissier EMSG("unexpected parameters"); 242963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 243963051aaSJerome Forissier } 244963051aaSJerome Forissier 245963051aaSJerome Forissier /* 246963051aaSJerome Forissier * Test access to Secure Data Path memory from pseudo TAs 247963051aaSJerome Forissier */ 248963051aaSJerome Forissier 249963051aaSJerome Forissier static TEE_Result test_inject_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS]) 250963051aaSJerome Forissier { 251963051aaSJerome Forissier char *src = p[0].memref.buffer; 252963051aaSJerome Forissier char *dst = p[1].memref.buffer; 253963051aaSJerome Forissier size_t sz = p[0].memref.size; 254963051aaSJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 255963051aaSJerome Forissier TEE_PARAM_TYPE_MEMREF_OUTPUT, 256963051aaSJerome Forissier TEE_PARAM_TYPE_NONE, 257963051aaSJerome Forissier TEE_PARAM_TYPE_NONE); 258963051aaSJerome Forissier 259963051aaSJerome Forissier if (exp_pt != type) { 260963051aaSJerome Forissier DMSG("bad parameter types"); 261963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 262963051aaSJerome Forissier } 263963051aaSJerome Forissier 264963051aaSJerome Forissier if (p[1].memref.size < sz) { 265963051aaSJerome Forissier p[1].memref.size = sz; 266963051aaSJerome Forissier return TEE_ERROR_SHORT_BUFFER; 267963051aaSJerome Forissier } 268963051aaSJerome Forissier 269963051aaSJerome Forissier if (!core_vbuf_is(CORE_MEM_NON_SEC, src, sz) || 270963051aaSJerome Forissier !core_vbuf_is(CORE_MEM_SDP_MEM, dst, sz)) { 271963051aaSJerome Forissier DMSG("bad memref secure attribute"); 272963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 273963051aaSJerome Forissier } 274963051aaSJerome Forissier 275963051aaSJerome Forissier if (!sz) 276963051aaSJerome Forissier return TEE_SUCCESS; 277963051aaSJerome Forissier 278963051aaSJerome Forissier /* Check that core can p2v and v2p over memory reference arguments */ 279c2e4eb43SAnton Rybakov if (test_v2p2v(src, sz) || test_v2p2v(dst, sz)) 280963051aaSJerome Forissier return TEE_ERROR_SECURITY; 281963051aaSJerome Forissier 282963051aaSJerome Forissier if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS) 283963051aaSJerome Forissier return TEE_ERROR_GENERIC; 284963051aaSJerome Forissier 285963051aaSJerome Forissier memcpy(dst, src, sz); 286963051aaSJerome Forissier 287963051aaSJerome Forissier if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS) 288963051aaSJerome Forissier return TEE_ERROR_GENERIC; 289963051aaSJerome Forissier 290963051aaSJerome Forissier return TEE_SUCCESS; 291963051aaSJerome Forissier } 292963051aaSJerome Forissier 293963051aaSJerome Forissier static TEE_Result test_transform_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS]) 294963051aaSJerome Forissier { 295963051aaSJerome Forissier char *buf = p[0].memref.buffer; 296963051aaSJerome Forissier size_t sz = p[0].memref.size; 297963051aaSJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 298963051aaSJerome Forissier TEE_PARAM_TYPE_NONE, 299963051aaSJerome Forissier TEE_PARAM_TYPE_NONE, 300963051aaSJerome Forissier TEE_PARAM_TYPE_NONE); 301963051aaSJerome Forissier 302963051aaSJerome Forissier if (exp_pt != type) { 303963051aaSJerome Forissier DMSG("bad parameter types"); 304963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 305963051aaSJerome Forissier } 306963051aaSJerome Forissier 307963051aaSJerome Forissier if (!core_vbuf_is(CORE_MEM_SDP_MEM, buf, sz)) { 308963051aaSJerome Forissier DMSG("bad memref secure attribute"); 309963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 310963051aaSJerome Forissier } 311963051aaSJerome Forissier 312963051aaSJerome Forissier if (!sz) 313963051aaSJerome Forissier return TEE_SUCCESS; 314963051aaSJerome Forissier 315963051aaSJerome Forissier /* Check that core can p2v and v2p over memory reference arguments */ 316c2e4eb43SAnton Rybakov if (test_v2p2v(buf, sz)) 317963051aaSJerome Forissier return TEE_ERROR_SECURITY; 318963051aaSJerome Forissier 319963051aaSJerome Forissier if (cache_operation(TEE_CACHEFLUSH, buf, sz) != TEE_SUCCESS) 320963051aaSJerome Forissier return TEE_ERROR_GENERIC; 321963051aaSJerome Forissier 322963051aaSJerome Forissier for (; sz; sz--, buf++) 323963051aaSJerome Forissier *buf = ~(*buf) + 1; 324963051aaSJerome Forissier 325963051aaSJerome Forissier if (cache_operation(TEE_CACHEFLUSH, buf, sz) != TEE_SUCCESS) 326963051aaSJerome Forissier return TEE_ERROR_GENERIC; 327963051aaSJerome Forissier 328963051aaSJerome Forissier return TEE_SUCCESS; 329963051aaSJerome Forissier } 330963051aaSJerome Forissier 331963051aaSJerome Forissier static TEE_Result test_dump_sdp(uint32_t type, TEE_Param p[TEE_NUM_PARAMS]) 332963051aaSJerome Forissier { 333963051aaSJerome Forissier char *src = p[0].memref.buffer; 334963051aaSJerome Forissier char *dst = p[1].memref.buffer; 335963051aaSJerome Forissier size_t sz = p[0].memref.size; 336963051aaSJerome Forissier uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 337963051aaSJerome Forissier TEE_PARAM_TYPE_MEMREF_OUTPUT, 338963051aaSJerome Forissier TEE_PARAM_TYPE_NONE, 339963051aaSJerome Forissier TEE_PARAM_TYPE_NONE); 340963051aaSJerome Forissier 341963051aaSJerome Forissier if (exp_pt != type) { 342963051aaSJerome Forissier DMSG("bad parameter types"); 343963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 344963051aaSJerome Forissier } 345963051aaSJerome Forissier 346963051aaSJerome Forissier if (p[1].memref.size < sz) { 347963051aaSJerome Forissier p[1].memref.size = sz; 348963051aaSJerome Forissier return TEE_ERROR_SHORT_BUFFER; 349963051aaSJerome Forissier } 350963051aaSJerome Forissier 351963051aaSJerome Forissier if (!core_vbuf_is(CORE_MEM_SDP_MEM, src, sz) || 352963051aaSJerome Forissier !core_vbuf_is(CORE_MEM_NON_SEC, dst, sz)) { 353963051aaSJerome Forissier DMSG("bad memref secure attribute"); 354963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 355963051aaSJerome Forissier } 356963051aaSJerome Forissier 357963051aaSJerome Forissier if (!sz) 358963051aaSJerome Forissier return TEE_SUCCESS; 359963051aaSJerome Forissier 360963051aaSJerome Forissier /* Check that core can p2v and v2p over memory reference arguments */ 361c2e4eb43SAnton Rybakov if (test_v2p2v(src, sz) || test_v2p2v(dst, sz)) 362963051aaSJerome Forissier return TEE_ERROR_SECURITY; 363963051aaSJerome Forissier 364963051aaSJerome Forissier if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS) 365963051aaSJerome Forissier return TEE_ERROR_GENERIC; 366963051aaSJerome Forissier 367963051aaSJerome Forissier memcpy(dst, src, sz); 368963051aaSJerome Forissier 369963051aaSJerome Forissier if (cache_operation(TEE_CACHEFLUSH, dst, sz) != TEE_SUCCESS) 370963051aaSJerome Forissier return TEE_ERROR_GENERIC; 371963051aaSJerome Forissier 372963051aaSJerome Forissier return TEE_SUCCESS; 373963051aaSJerome Forissier } 374963051aaSJerome Forissier 375963051aaSJerome Forissier /* 376963051aaSJerome Forissier * Trusted Application Entry Points 377963051aaSJerome Forissier */ 378963051aaSJerome Forissier 379963051aaSJerome Forissier static TEE_Result create_ta(void) 380963051aaSJerome Forissier { 381963051aaSJerome Forissier DMSG("create entry point for pseudo TA \"%s\"", TA_NAME); 382963051aaSJerome Forissier return TEE_SUCCESS; 383963051aaSJerome Forissier } 384963051aaSJerome Forissier 385963051aaSJerome Forissier static void destroy_ta(void) 386963051aaSJerome Forissier { 387963051aaSJerome Forissier DMSG("destroy entry point for pseudo ta \"%s\"", TA_NAME); 388963051aaSJerome Forissier } 389963051aaSJerome Forissier 390963051aaSJerome Forissier static TEE_Result open_session(uint32_t nParamTypes __unused, 391963051aaSJerome Forissier TEE_Param pParams[TEE_NUM_PARAMS] __unused, 392963051aaSJerome Forissier void **ppSessionContext __unused) 393963051aaSJerome Forissier { 394963051aaSJerome Forissier DMSG("open entry point for pseudo ta \"%s\"", TA_NAME); 395963051aaSJerome Forissier return TEE_SUCCESS; 396963051aaSJerome Forissier } 397963051aaSJerome Forissier 398963051aaSJerome Forissier static void close_session(void *pSessionContext __unused) 399963051aaSJerome Forissier { 400963051aaSJerome Forissier DMSG("close entry point for pseudo ta \"%s\"", TA_NAME); 401963051aaSJerome Forissier } 402963051aaSJerome Forissier 403963051aaSJerome Forissier static TEE_Result invoke_command(void *pSessionContext __unused, 404963051aaSJerome Forissier uint32_t nCommandID, uint32_t nParamTypes, 405963051aaSJerome Forissier TEE_Param pParams[TEE_NUM_PARAMS]) 406963051aaSJerome Forissier { 407963051aaSJerome Forissier FMSG("command entry point for pseudo ta \"%s\"", TA_NAME); 408963051aaSJerome Forissier 409963051aaSJerome Forissier switch (nCommandID) { 410963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_TRACE: 411963051aaSJerome Forissier return test_trace(nParamTypes, pParams); 412963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_PARAMS: 413963051aaSJerome Forissier return test_entry_params(nParamTypes, pParams); 414b213d8bdSEtienne Carriere case PTA_INVOKE_TESTS_CMD_MEMREF_NULL: 415b213d8bdSEtienne Carriere return test_entry_memref_null(nParamTypes, pParams); 416963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_COPY_NSEC_TO_SEC: 417963051aaSJerome Forissier return test_inject_sdp(nParamTypes, pParams); 418963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_READ_MODIFY_SEC: 419963051aaSJerome Forissier return test_transform_sdp(nParamTypes, pParams); 420963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_COPY_SEC_TO_NSEC: 421963051aaSJerome Forissier return test_dump_sdp(nParamTypes, pParams); 422963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_SELF_TESTS: 423963051aaSJerome Forissier return core_self_tests(nParamTypes, pParams); 424c6b34ea8SJerome Forissier #if defined(CFG_REE_FS) && defined(CFG_WITH_USER_TA) 425963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_FS_HTREE: 426963051aaSJerome Forissier return core_fs_htree_tests(nParamTypes, pParams); 427963051aaSJerome Forissier #endif 428963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_MUTEX: 429963051aaSJerome Forissier return core_mutex_tests(nParamTypes, pParams); 430963051aaSJerome Forissier case PTA_INVOKE_TESTS_CMD_LOCKDEP: 431963051aaSJerome Forissier return core_lockdep_tests(nParamTypes, pParams); 43285898338SJens Wiklander case PTA_INVOKE_TEST_CMD_AES_PERF: 43385898338SJens Wiklander return core_aes_perf_tests(nParamTypes, pParams); 434d783b681SEtienne Carriere case PTA_INVOKE_TESTS_CMD_DT_DRIVER_TESTS: 435d783b681SEtienne Carriere return core_dt_driver_tests(nParamTypes, pParams); 436963051aaSJerome Forissier default: 437963051aaSJerome Forissier break; 438963051aaSJerome Forissier } 439963051aaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 440963051aaSJerome Forissier } 441963051aaSJerome Forissier 442963051aaSJerome Forissier pseudo_ta_register(.uuid = PTA_INVOKE_TESTS_UUID, .name = TA_NAME, 443963051aaSJerome Forissier .flags = PTA_DEFAULT_FLAGS | TA_FLAG_SECURE_DATA_PATH | 4443db0071cSJens Wiklander TA_FLAG_CONCURRENT | TA_FLAG_DEVICE_ENUM, 445963051aaSJerome Forissier .create_entry_point = create_ta, 446963051aaSJerome Forissier .destroy_entry_point = destroy_ta, 447963051aaSJerome Forissier .open_session_entry_point = open_session, 448963051aaSJerome Forissier .close_session_entry_point = close_session, 449963051aaSJerome Forissier .invoke_command_entry_point = invoke_command); 450