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