blob: 0e8e5b235d01753192546cf3308d9d5ea55775d4 [file] [log] [blame]
Etienne Carriere75141172020-05-16 11:58:23 +02001// SPDX-License-Identifier: BSD-2-Clause
Pascal Brandc639ac82015-07-02 08:53:34 +02002/*
3 * Copyright (c) 2014, STMicroelectronics International N.V.
4 * All rights reserved.
Pascal Brandc639ac82015-07-02 08:53:34 +02005 */
6
7#include <ta_sims.h>
8#include <tee_api.h>
9
10#define TA_SIMS_MAX_STORAGE 4
11
12struct sims_bucket {
13 uint32_t size;
14 void *data;
15};
16
17struct sims_session {
Ovidiu Mihalachi7d6e63b2019-04-02 13:48:09 +030018 TEE_TASessionHandle sess;
Pascal Brandc639ac82015-07-02 08:53:34 +020019 uint32_t counter;
20 uint32_t array[2048];
21};
22
23static struct sims_bucket storage[TA_SIMS_MAX_STORAGE] = { {0} };
24
25static uint32_t counter;
26
Ovidiu Mihalachi7d6e63b2019-04-02 13:48:09 +030027TEE_Result sims_open_ta_session(void *session_context, uint32_t param_types,
28 TEE_Param params[4])
29{
30 TEE_UUID *uuid = NULL;
31 TEE_Result res = TEE_SUCCESS;
32 TEE_TASessionHandle sess = TEE_HANDLE_NULL;
33 uint32_t ret_orig = 0;
34 struct sims_session *ctx = (struct sims_session *)session_context;
35
36 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
37 TEE_PARAM_TYPE_NONE,
38 TEE_PARAM_TYPE_NONE,
39 TEE_PARAM_TYPE_NONE))
40 return TEE_ERROR_BAD_PARAMETERS;
41
42 if (params[0].memref.size != sizeof(*uuid))
43 return TEE_ERROR_BAD_PARAMETERS;
44
45 uuid = TEE_Malloc(sizeof(*uuid), TEE_MALLOC_FILL_ZERO);
46 if (!uuid)
47 return TEE_ERROR_OUT_OF_MEMORY;
48
49 TEE_MemMove(uuid, params[0].memref.buffer, params[0].memref.size);
50
Cedric Augere668b3f2019-09-11 13:41:21 +020051 res = TEE_OpenTASession(uuid, TEE_TIMEOUT_INFINITE, 0, NULL,
52 &sess, &ret_orig);
Ovidiu Mihalachi7d6e63b2019-04-02 13:48:09 +030053 TEE_Free(uuid);
54 if (res != TEE_SUCCESS)
55 return res;
56
57 ctx->sess = sess;
58 ctx->counter++;
59
60 return TEE_SUCCESS;
61}
62
Pascal Brandc639ac82015-07-02 08:53:34 +020063TEE_Result sims_open_session(void **ctx)
64{
65 struct sims_session *context =
Ovidiu Mihalachi7d6e63b2019-04-02 13:48:09 +030066 TEE_Malloc(sizeof(struct sims_session), TEE_MALLOC_FILL_ZERO);
Etienne Carriere102092e2019-03-28 15:24:22 +010067
Pascal Brandc639ac82015-07-02 08:53:34 +020068 if (context == NULL)
69 return TEE_ERROR_OUT_OF_MEMORY;
70
Ovidiu Mihalachi7d6e63b2019-04-02 13:48:09 +030071 context->sess = TEE_HANDLE_NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +020072 context->counter = counter;
73 *ctx = context;
74
75 counter++;
76
77 return TEE_SUCCESS;
78}
79
80void sims_close_session(void *ctx)
81{
Ovidiu Mihalachi7d6e63b2019-04-02 13:48:09 +030082 TEE_TASessionHandle sess = ((struct sims_session *)ctx)->sess;
83
84 if (sess != TEE_HANDLE_NULL)
85 TEE_CloseTASession(sess);
86
Pascal Brandc639ac82015-07-02 08:53:34 +020087 TEE_Free(ctx);
88}
89
90TEE_Result sims_read(uint32_t param_types, TEE_Param params[4])
91{
Etienne Carriere102092e2019-03-28 15:24:22 +010092 uint32_t index = 0;
93 void *p = NULL;
Pascal Brandc639ac82015-07-02 08:53:34 +020094
95 if (param_types !=
96 TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
97 TEE_PARAM_TYPE_MEMREF_OUTPUT, 0, 0))
98 return TEE_ERROR_BAD_PARAMETERS;
99
100 index = params[0].value.a;
101 if (index >= TA_SIMS_MAX_STORAGE)
102 return TEE_ERROR_BAD_PARAMETERS;
103
104 if (storage[index].size > params[1].memref.size)
105 return TEE_ERROR_OVERFLOW;
106
107 p = TEE_Malloc(16000, 0);
108 if (p == NULL)
109 return TEE_ERROR_OUT_OF_MEMORY;
110
111 TEE_MemMove(params[1].memref.buffer, storage[index].data,
112 params[1].memref.size);
113
114 TEE_Free(p);
115
116 return TEE_SUCCESS;
117}
118
119TEE_Result sims_write(uint32_t param_types, TEE_Param params[4])
120{
Etienne Carriere102092e2019-03-28 15:24:22 +0100121 uint32_t index = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200122
123 if (param_types !=
124 TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
125 TEE_PARAM_TYPE_MEMREF_INPUT, 0, 0))
126 return TEE_ERROR_BAD_PARAMETERS;
127
128 index = params[0].value.a;
129 if (index >= TA_SIMS_MAX_STORAGE)
130 return TEE_ERROR_BAD_PARAMETERS;
131
132 if (storage[index].data != NULL)
133 TEE_Free(storage[index].data);
134
135 storage[index].data = TEE_Malloc(params[1].memref.size, 0);
136 if (storage[index].data == NULL) {
137 storage[index].size = 0;
138 return TEE_ERROR_OUT_OF_MEMORY;
139 }
140 storage[index].size = params[1].memref.size;
141
142 TEE_MemMove(storage[index].data, params[1].memref.buffer,
143 params[1].memref.size);
144
145 return TEE_SUCCESS;
146}
147
148TEE_Result sims_get_counter(void *session_context, uint32_t param_types,
149 TEE_Param params[4])
150{
151 struct sims_session *ctx = (struct sims_session *)session_context;
152
153 if (param_types !=
154 TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT, 0, 0, 0))
155 return TEE_ERROR_BAD_PARAMETERS;
156
157 params[0].value.a = ctx->counter;
158
159 return TEE_SUCCESS;
160}
Ovidiu Mihalachib17b75c2018-12-04 10:37:50 +0200161
162TEE_Result sims_entry_panic(void *session_context, uint32_t param_types,
163 TEE_Param params[4])
164{
Ovidiu Mihalachi7d6e63b2019-04-02 13:48:09 +0300165 uint32_t ret_orig = 0;
166 TEE_Result res = TEE_SUCCESS;
167 struct sims_session *ctx = (struct sims_session *)session_context;
Ovidiu Mihalachib17b75c2018-12-04 10:37:50 +0200168
Ovidiu Mihalachi7d6e63b2019-04-02 13:48:09 +0300169 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
170 TEE_PARAM_TYPE_NONE,
171 TEE_PARAM_TYPE_NONE,
172 TEE_PARAM_TYPE_NONE))
173 return TEE_ERROR_BAD_PARAMETERS;
174
175 if (params[0].memref.buffer && params[0].memref.size) {
176 res = sims_open_ta_session(session_context,
177 param_types, params);
178 if (res != TEE_SUCCESS)
179 return res;
180
181 params[0].memref.buffer = NULL;
182 params[0].memref.size = 0;
183
184 /* Trigger panic to remote TA */
Cedric Augere668b3f2019-09-11 13:41:21 +0200185 (void)TEE_InvokeTACommand(ctx->sess, TEE_TIMEOUT_INFINITE,
Ovidiu Mihalachi7d6e63b2019-04-02 13:48:09 +0300186 TA_SIMS_CMD_PANIC,
187 param_types, params,
188 &ret_orig);
189 } else {
190 TEE_Panic(0xbeef); /* Trigger panic to current TA */
191 }
Ovidiu Mihalachib17b75c2018-12-04 10:37:50 +0200192
193 return TEE_SUCCESS;
194}