xref: /OK3568_Linux_fs/buildroot/package/rockchip/tee-user-app/extra_app/ta/keybox.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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)&params;
40 	(void)&sess_ctx;
41 	(void)&param_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