1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2021 Rockchip Electronics Co. Ltd.
4 */
5
6 #include <tee_internal_api.h>
7 #include <tee_internal_api_extensions.h>
8 #include <tee_api_defines.h>
9 #include "ta_keybox.h"
10 #include <tee_api.h>
11 #include "../rk_public_api/rk_trng_api.h"
12
13 /*
14 * Called when the instance of the TA is created. This is the first call in
15 * the TA.
16 */
TA_CreateEntryPoint(void)17 TEE_Result TA_CreateEntryPoint(void)
18 {
19 return TEE_SUCCESS;
20 }
21
22 /*
23 * Called when the instance of the TA is destroyed if the TA has not
24 * crashed or panicked. This is the last call in the TA.
25 */
TA_DestroyEntryPoint(void)26 void TA_DestroyEntryPoint(void)
27 {
28 }
29
30 /*
31 * Called when a new session is opened to the TA. *sess_ctx can be updated
32 * with a value to be able to identify this session in subsequent calls to the
33 * TA.
34 */
TA_OpenSessionEntryPoint(uint32_t param_types,TEE_Param params[4],void ** sess_ctx)35 TEE_Result TA_OpenSessionEntryPoint(uint32_t param_types,
36 TEE_Param params[4], void **sess_ctx)
37 {
38 /* Unused parameters */
39 (void)¶ms;
40 (void)&sess_ctx;
41 (void)¶m_types;
42
43 /* If return value != TEE_SUCCESS the session will not be created. */
44 return TEE_SUCCESS;
45 }
46
47 /*
48 * Called when a session is closed, sess_ctx hold the value that was
49 * assigned by TA_OpenSessionEntryPoint().
50 */
TA_CloseSessionEntryPoint(void * sess_ctx)51 void TA_CloseSessionEntryPoint(void *sess_ctx)
52 {
53 (void)&sess_ctx; /* Unused parameter */
54 }
55
TA_TouchtHandle(uint32_t type,uint8_t * id,int len,uint32_t flags,TEE_ObjectHandle * handle)56 static TEE_Result TA_TouchtHandle(uint32_t type, uint8_t *id, int len,
57 uint32_t flags, TEE_ObjectHandle *handle)
58 {
59 TEE_Result res = TEE_SUCCESS;
60
61 res = TEE_OpenPersistentObject(type, id, len, flags, handle);
62 if (res == TEE_SUCCESS)
63 return res;
64
65 res = TEE_CreatePersistentObject(type, id, len, flags,
66 TEE_HANDLE_NULL, NULL, 0,
67 handle);
68 return res;
69 }
70
js_hash(uint32_t hash,uint8_t * buf,int len)71 static uint32_t js_hash(uint32_t hash, uint8_t *buf, int len)
72 {
73 int i;
74
75 for (i = 0; i < len; i++)
76 hash ^= ((hash << 5) + buf[i] + (hash >> 2));
77
78 return hash;
79 }
80
81 /*
82 * Called when a TA is invoked. sess_ctx hold that value that was
83 * assigned by TA_OpenSessionEntryPoint(). The rest of the parameters
84 * comes from normal world.
85 */
86 static uint32_t g_hash = 0;
87 static uint32_t g_ver = 0;
TA_InvokeCommandEntryPoint(void * sess_ctx,uint32_t cmd_id,uint32_t param_types,TEE_Param params[4])88 TEE_Result TA_InvokeCommandEntryPoint(void *sess_ctx, uint32_t cmd_id,
89 uint32_t param_types, TEE_Param params[4])
90 {
91 /* Unused parameters */
92 (void)&sess_ctx;
93 uint32_t exp_param_types;
94 TEE_Result res = TEE_SUCCESS;
95 uint32_t flags = TEE_DATA_FLAG_ACCESS_READ |
96 TEE_DATA_FLAG_ACCESS_WRITE |
97 TEE_DATA_FLAG_ACCESS_WRITE_META;
98 TEE_ObjectHandle ob_handle;
99 uint8_t id[] = "enc_key";
100 uint32_t count = 0;
101 void *buf = NULL;
102
103 buf = TEE_Malloc(64, 0);
104 if (!buf)
105 return TEE_ERROR_OUT_OF_MEMORY;
106
107 switch (cmd_id) {
108 case TA_KEY_RNG:
109 exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT,
110 TEE_PARAM_TYPE_NONE,
111 TEE_PARAM_TYPE_NONE,
112 TEE_PARAM_TYPE_NONE);
113 if (param_types != exp_param_types)
114 return TEE_ERROR_BAD_PARAMETERS;
115
116 res = rk_get_trng(buf, params[0].memref.size);
117 if (res != TEE_SUCCESS) {
118 EMSG("rk_get_trng failed with code 0x%x", res);
119 goto out;
120 }
121
122 g_hash = js_hash(0x47c6a7e6, buf, params[0].memref.size);
123 TEE_MemMove(params[0].memref.buffer, buf, params[0].memref.size);
124 break;
125 case TA_KEY_VER:
126 exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
127 TEE_PARAM_TYPE_NONE,
128 TEE_PARAM_TYPE_NONE,
129 TEE_PARAM_TYPE_NONE);
130 if (param_types != exp_param_types)
131 return TEE_ERROR_BAD_PARAMETERS;
132
133 if (g_hash && (g_hash == params[0].value.a)) {
134 //IMSG("******** PASS");
135 g_ver = 1;
136 } else {
137 //IMSG("******** failed (g_hash = %x)", g_hash);
138 g_ver = 0;
139 }
140
141 break;
142 case TA_KEY_READ:
143 exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT,
144 TEE_PARAM_TYPE_VALUE_INPUT,
145 TEE_PARAM_TYPE_NONE,
146 TEE_PARAM_TYPE_NONE);
147 if (param_types != exp_param_types)
148 return TEE_ERROR_BAD_PARAMETERS;
149
150 if (params[0].memref.size > 64)
151 return TEE_ERROR_BAD_PARAMETERS;
152
153 if (!g_ver) {
154 res = rk_get_trng(buf, params[0].memref.size);
155 if (res != TEE_SUCCESS)
156 EMSG("rk_get_trng failed with code 0x%x", res);
157 } else {
158 res = TEE_OpenPersistentObject(params[1].value.a,
159 id, sizeof(id), flags,
160 &ob_handle);
161
162 if (res != TEE_SUCCESS) {
163 EMSG("OpenPersistentObject ERR: 0x%x.", res);
164 break;
165 }
166
167 res = TEE_ReadObjectData(ob_handle, buf,
168 params[0].memref.size, &count);
169 if (res != TEE_SUCCESS) {
170 EMSG("ReadObjectData ERR: 0x%x.", res);
171 goto out_r;
172 }
173
174 if (count != params[0].memref.size)
175 res = TEE_ERROR_OUT_OF_MEMORY;
176 out_r:
177 TEE_CloseObject(ob_handle);
178 }
179 TEE_MemMove(params[0].memref.buffer, buf, params[0].memref.size);
180
181 break;
182 case TA_KEY_WRITE:
183 exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
184 TEE_PARAM_TYPE_VALUE_INPUT,
185 TEE_PARAM_TYPE_NONE,
186 TEE_PARAM_TYPE_NONE);
187 if (param_types != exp_param_types)
188 return TEE_ERROR_BAD_PARAMETERS;
189
190 if (params[0].memref.size > 64)
191 return TEE_ERROR_BAD_PARAMETERS;
192
193 TEE_MemMove(buf, params[0].memref.buffer, params[0].memref.size);
194
195 /* Try to get handle if node exist */
196 res = TA_TouchtHandle(params[1].value.a, id, sizeof(id),
197 flags, &ob_handle);
198
199 if (res != TEE_SUCCESS)
200 break;
201
202 res = TEE_SeekObjectData(ob_handle, 0, TEE_DATA_SEEK_SET);
203 if (res != TEE_SUCCESS) {
204 EMSG("SeekObjectData ERR: 0x%x.", res);
205 goto out_w;
206 }
207
208 res = TEE_WriteObjectData(ob_handle, buf, params[0].memref.size);
209 if (res != TEE_SUCCESS) {
210 EMSG("WriteObjectData ERR: 0x%x.", res);
211 goto out_w;
212 }
213 out_w:
214 TEE_CloseObject(ob_handle);
215 break;
216 default:
217 break;
218 }
219
220 out:
221 if (buf)
222 TEE_Free(buf);
223
224 return res;
225 }
226