xref: /OK3568_Linux_fs/u-boot/common/write_keybox.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <common.h>
7*4882a593Smuzhiyun #include <boot_rkimg.h>
8*4882a593Smuzhiyun #include <stdlib.h>
9*4882a593Smuzhiyun #include <attestation_key.h>
10*4882a593Smuzhiyun #include <write_keybox.h>
11*4882a593Smuzhiyun #include <keymaster.h>
12*4882a593Smuzhiyun #include <optee_include/OpteeClientApiLib.h>
13*4882a593Smuzhiyun #include <optee_include/tee_client_api.h>
14*4882a593Smuzhiyun #include <optee_include/tee_api_defines.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #define STORAGE_CMD_WRITE	6
17*4882a593Smuzhiyun #define	SIZE_OF_TAG		4
18*4882a593Smuzhiyun #define	BOOT_FROM_EMMC	(1 << 1)
19*4882a593Smuzhiyun #define	WIDEVINE_TAG	"KBOX"
20*4882a593Smuzhiyun #define	ATTESTATION_TAG	"ATTE"
21*4882a593Smuzhiyun #define PLAYREADY30_TAG	"SL30"
22*4882a593Smuzhiyun 
write_to_security_storage(uint8_t is_use_rpmb,uint8_t * filename,uint32_t filename_size,uint8_t * data,uint32_t data_size)23*4882a593Smuzhiyun TEEC_Result write_to_security_storage(uint8_t is_use_rpmb,
24*4882a593Smuzhiyun 				      uint8_t *filename,
25*4882a593Smuzhiyun 				      uint32_t filename_size,
26*4882a593Smuzhiyun 				      uint8_t *data,
27*4882a593Smuzhiyun 				      uint32_t data_size)
28*4882a593Smuzhiyun {
29*4882a593Smuzhiyun 	TEEC_Result TeecResult;
30*4882a593Smuzhiyun 	TEEC_Context TeecContext;
31*4882a593Smuzhiyun 	TEEC_Session TeecSession;
32*4882a593Smuzhiyun 	TEEC_SharedMemory SharedMem0 = {0};
33*4882a593Smuzhiyun 	TEEC_SharedMemory SharedMem1 = {0};
34*4882a593Smuzhiyun 	uint32_t ErrorOrigin;
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 	TEEC_UUID tempuuid = { 0x1b484ea5,
37*4882a593Smuzhiyun 			       0x698b,
38*4882a593Smuzhiyun 			       0x4142,
39*4882a593Smuzhiyun 			       { 0x82, 0xb8, 0x3a,
40*4882a593Smuzhiyun 				 0xcf, 0x16, 0xe9,
41*4882a593Smuzhiyun 				 0x9e, 0x2a } };
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	TEEC_UUID *TeecUuid = &tempuuid;
44*4882a593Smuzhiyun 	TEEC_Operation TeecOperation = {0};
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 	TeecResult = OpteeClientApiLibInitialize();
47*4882a593Smuzhiyun 	if (TeecResult) {
48*4882a593Smuzhiyun 		printf("OpteeClientApiLibInitialize fail\n");
49*4882a593Smuzhiyun 		return TeecResult;
50*4882a593Smuzhiyun 	}
51*4882a593Smuzhiyun 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
52*4882a593Smuzhiyun 	if (TeecResult) {
53*4882a593Smuzhiyun 		printf("TEEC_InitializeContext fail\n");
54*4882a593Smuzhiyun 		return TeecResult;
55*4882a593Smuzhiyun 	}
56*4882a593Smuzhiyun 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
57*4882a593Smuzhiyun 						    TEEC_NONE,
58*4882a593Smuzhiyun 						    TEEC_NONE,
59*4882a593Smuzhiyun 						    TEEC_NONE);
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	/*0 nand or emmc "security" partition , 1 rpmb*/
62*4882a593Smuzhiyun 	TeecOperation.params[0].value.a = is_use_rpmb;
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	TeecResult = TEEC_OpenSession(&TeecContext,
65*4882a593Smuzhiyun 				      &TeecSession,
66*4882a593Smuzhiyun 				      TeecUuid,
67*4882a593Smuzhiyun 				      TEEC_LOGIN_PUBLIC,
68*4882a593Smuzhiyun 				      NULL, &TeecOperation,
69*4882a593Smuzhiyun 				      &ErrorOrigin);
70*4882a593Smuzhiyun 	if (TeecResult) {
71*4882a593Smuzhiyun 		printf("TEEC_OpenSession fail\n");
72*4882a593Smuzhiyun 		return TeecResult;
73*4882a593Smuzhiyun 	}
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	SharedMem0.size = filename_size;
76*4882a593Smuzhiyun 	SharedMem0.flags = 0;
77*4882a593Smuzhiyun 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
78*4882a593Smuzhiyun 	if (TeecResult) {
79*4882a593Smuzhiyun 		printf("TEEC_AllocateSharedMemory fail\n");
80*4882a593Smuzhiyun 		return TeecResult;
81*4882a593Smuzhiyun 	}
82*4882a593Smuzhiyun 	memcpy(SharedMem0.buffer, filename, SharedMem0.size);
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	SharedMem1.size = data_size;
85*4882a593Smuzhiyun 	SharedMem1.flags = 0;
86*4882a593Smuzhiyun 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem1);
87*4882a593Smuzhiyun 	if (TeecResult) {
88*4882a593Smuzhiyun 		printf("TEEC_AllocateSharedMemory fail\n");
89*4882a593Smuzhiyun 		return TeecResult;
90*4882a593Smuzhiyun 	}
91*4882a593Smuzhiyun 	memcpy(SharedMem1.buffer, data, SharedMem1.size);
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
94*4882a593Smuzhiyun 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	TeecOperation.params[1].tmpref.buffer = SharedMem1.buffer;
97*4882a593Smuzhiyun 	TeecOperation.params[1].tmpref.size = SharedMem1.size;
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
100*4882a593Smuzhiyun 						    TEEC_MEMREF_TEMP_INOUT,
101*4882a593Smuzhiyun 						    TEEC_NONE,
102*4882a593Smuzhiyun 						    TEEC_NONE);
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	TeecResult = TEEC_InvokeCommand(&TeecSession,
105*4882a593Smuzhiyun 					1,
106*4882a593Smuzhiyun 					&TeecOperation,
107*4882a593Smuzhiyun 					&ErrorOrigin);
108*4882a593Smuzhiyun 	if (TeecResult) {
109*4882a593Smuzhiyun 		printf("TEEC_InvokeCommand fail\n");
110*4882a593Smuzhiyun 		return TeecResult;
111*4882a593Smuzhiyun 	}
112*4882a593Smuzhiyun 	TEEC_ReleaseSharedMemory(&SharedMem0);
113*4882a593Smuzhiyun 	TEEC_ReleaseSharedMemory(&SharedMem1);
114*4882a593Smuzhiyun 	TEEC_CloseSession(&TeecSession);
115*4882a593Smuzhiyun 	TEEC_FinalizeContext(&TeecContext);
116*4882a593Smuzhiyun 	debug("TeecResult %x\n", TeecResult);
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	return TeecResult;
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun 
rk_send_keybox_to_ta(uint8_t * filename,uint32_t filename_size,TEEC_UUID uuid,uint8_t * key,uint32_t key_size,uint8_t * data,uint32_t data_size)121*4882a593Smuzhiyun uint32_t rk_send_keybox_to_ta(uint8_t *filename, uint32_t filename_size,
122*4882a593Smuzhiyun 			      TEEC_UUID uuid,
123*4882a593Smuzhiyun 			      uint8_t *key, uint32_t key_size,
124*4882a593Smuzhiyun 			      uint8_t *data, uint32_t data_size)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun 	uint32_t ErrorOrigin;
127*4882a593Smuzhiyun 	TEEC_Result TeecResult;
128*4882a593Smuzhiyun 	TEEC_Context TeecContext;
129*4882a593Smuzhiyun 	TEEC_Session TeecSession;
130*4882a593Smuzhiyun 	TEEC_UUID *TeecUuid = &uuid;
131*4882a593Smuzhiyun 	TEEC_Operation TeecOperation = {0};
132*4882a593Smuzhiyun 	TEEC_SharedMemory SharedMem0 = {0};
133*4882a593Smuzhiyun 	TEEC_SharedMemory SharedMem1 = {0};
134*4882a593Smuzhiyun 	TEEC_SharedMemory SharedMem2 = {0};
135*4882a593Smuzhiyun 	struct blk_desc *dev_desc;
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	dev_desc = rockchip_get_bootdev();
138*4882a593Smuzhiyun 	if (!dev_desc) {
139*4882a593Smuzhiyun 		printf("%s: dev_desc is NULL!\n", __func__);
140*4882a593Smuzhiyun 		return -TEEC_ERROR_GENERIC;
141*4882a593Smuzhiyun 	}
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	TeecResult = OpteeClientApiLibInitialize();
144*4882a593Smuzhiyun 	if (TeecResult != TEEC_SUCCESS)
145*4882a593Smuzhiyun 		return TeecResult;
146*4882a593Smuzhiyun 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
147*4882a593Smuzhiyun 	if (TeecResult != TEEC_SUCCESS)
148*4882a593Smuzhiyun 		return TeecResult;
149*4882a593Smuzhiyun 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
150*4882a593Smuzhiyun 						    TEEC_NONE,
151*4882a593Smuzhiyun 						    TEEC_NONE,
152*4882a593Smuzhiyun 						    TEEC_NONE);
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	/* 0 nand or emmc "security" partition , 1 rpmb */
155*4882a593Smuzhiyun 	TeecOperation.params[0].value.a =
156*4882a593Smuzhiyun 		(dev_desc->if_type == IF_TYPE_MMC) ? 1 : 0;
157*4882a593Smuzhiyun #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
158*4882a593Smuzhiyun 	TeecOperation.params[0].value.a = 0;
159*4882a593Smuzhiyun #endif
160*4882a593Smuzhiyun 	TeecResult = TEEC_OpenSession(&TeecContext,
161*4882a593Smuzhiyun 				      &TeecSession,
162*4882a593Smuzhiyun 				      TeecUuid,
163*4882a593Smuzhiyun 				      TEEC_LOGIN_PUBLIC,
164*4882a593Smuzhiyun 				      NULL,
165*4882a593Smuzhiyun 				      &TeecOperation,
166*4882a593Smuzhiyun 				      &ErrorOrigin);
167*4882a593Smuzhiyun 	if (TeecResult != TEEC_SUCCESS)
168*4882a593Smuzhiyun 		return TeecResult;
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	SharedMem0.size = filename_size;
171*4882a593Smuzhiyun 	SharedMem0.flags = 0;
172*4882a593Smuzhiyun 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
173*4882a593Smuzhiyun 	if (TeecResult != TEEC_SUCCESS)
174*4882a593Smuzhiyun 		return TeecResult;
175*4882a593Smuzhiyun 	memcpy(SharedMem0.buffer, filename, SharedMem0.size);
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	SharedMem1.size = key_size;
178*4882a593Smuzhiyun 	SharedMem1.flags = 0;
179*4882a593Smuzhiyun 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem1);
180*4882a593Smuzhiyun 	if (TeecResult != TEEC_SUCCESS)
181*4882a593Smuzhiyun 		return TeecResult;
182*4882a593Smuzhiyun 	memcpy(SharedMem1.buffer, key, SharedMem1.size);
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	SharedMem2.size = data_size;
185*4882a593Smuzhiyun 	SharedMem2.flags = 0;
186*4882a593Smuzhiyun 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem2);
187*4882a593Smuzhiyun 	if (TeecResult != TEEC_SUCCESS)
188*4882a593Smuzhiyun 		return TeecResult;
189*4882a593Smuzhiyun 	memcpy(SharedMem2.buffer, data, SharedMem2.size);
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
192*4882a593Smuzhiyun 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
193*4882a593Smuzhiyun 	TeecOperation.params[1].tmpref.buffer = SharedMem1.buffer;
194*4882a593Smuzhiyun 	TeecOperation.params[1].tmpref.size = SharedMem1.size;
195*4882a593Smuzhiyun 	TeecOperation.params[2].tmpref.buffer = SharedMem2.buffer;
196*4882a593Smuzhiyun 	TeecOperation.params[2].tmpref.size = SharedMem2.size;
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
199*4882a593Smuzhiyun 						    TEEC_MEMREF_TEMP_INPUT,
200*4882a593Smuzhiyun 						    TEEC_MEMREF_TEMP_INOUT,
201*4882a593Smuzhiyun 						    TEEC_NONE);
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	printf("write keybox to secure storage\n");
204*4882a593Smuzhiyun 	TeecResult = TEEC_InvokeCommand(&TeecSession,
205*4882a593Smuzhiyun 					STORAGE_CMD_WRITE,
206*4882a593Smuzhiyun 					&TeecOperation,
207*4882a593Smuzhiyun 					&ErrorOrigin);
208*4882a593Smuzhiyun 	if (TeecResult != TEEC_SUCCESS)
209*4882a593Smuzhiyun 		printf("send data to TA failed with code 0x%x\n", TeecResult);
210*4882a593Smuzhiyun 	else
211*4882a593Smuzhiyun 		printf("send data to TA success with code 0x%x\n", TeecResult);
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	TEEC_ReleaseSharedMemory(&SharedMem0);
214*4882a593Smuzhiyun 	TEEC_ReleaseSharedMemory(&SharedMem1);
215*4882a593Smuzhiyun 	TEEC_ReleaseSharedMemory(&SharedMem2);
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	TEEC_CloseSession(&TeecSession);
218*4882a593Smuzhiyun 	TEEC_FinalizeContext(&TeecContext);
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	return TeecResult;
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun 
write_keybox_to_secure_storage(uint8_t * received_data,uint32_t len)223*4882a593Smuzhiyun uint32_t write_keybox_to_secure_storage(uint8_t *received_data, uint32_t len)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun 	uint8_t *widevine_data;
226*4882a593Smuzhiyun 	uint8_t *attestation_data;
227*4882a593Smuzhiyun 	uint8_t *playready_sl30_data;
228*4882a593Smuzhiyun 	uint32_t key_size;
229*4882a593Smuzhiyun 	uint32_t data_size;
230*4882a593Smuzhiyun 	int rc = 0;
231*4882a593Smuzhiyun 	TEEC_Result ret;
232*4882a593Smuzhiyun 	struct blk_desc *dev_desc;
233*4882a593Smuzhiyun 	uint8_t is_use_rpmb;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	dev_desc = rockchip_get_bootdev();
236*4882a593Smuzhiyun 	if (!dev_desc) {
237*4882a593Smuzhiyun 		printf("%s: dev_desc is NULL!\n", __func__);
238*4882a593Smuzhiyun 		return -EIO;
239*4882a593Smuzhiyun 	}
240*4882a593Smuzhiyun 	is_use_rpmb = (dev_desc->if_type == IF_TYPE_MMC) ? 1 : 0;
241*4882a593Smuzhiyun #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
242*4882a593Smuzhiyun 	is_use_rpmb = 0;
243*4882a593Smuzhiyun #endif
244*4882a593Smuzhiyun 	if (is_use_rpmb)
245*4882a593Smuzhiyun 		printf("I will write key to rpmb\n");
246*4882a593Smuzhiyun 	else
247*4882a593Smuzhiyun 		printf("I will write key to security partition\n");
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 	rc = write_to_security_storage(0, (uint8_t *)"security_partition",
250*4882a593Smuzhiyun 				       sizeof("security_partition"),
251*4882a593Smuzhiyun 				       &is_use_rpmb, sizeof(is_use_rpmb));
252*4882a593Smuzhiyun 	if (rc)
253*4882a593Smuzhiyun 		return -EIO;
254*4882a593Smuzhiyun 	widevine_data = (uint8_t *)new_strstr((char *)received_data,
255*4882a593Smuzhiyun 					      WIDEVINE_TAG, len);
256*4882a593Smuzhiyun 	attestation_data = (uint8_t *)new_strstr((char *)received_data,
257*4882a593Smuzhiyun 						 ATTESTATION_TAG, len);
258*4882a593Smuzhiyun 	playready_sl30_data = (uint8_t *)new_strstr((char *)received_data,
259*4882a593Smuzhiyun 						    PLAYREADY30_TAG, len);
260*4882a593Smuzhiyun 	if (widevine_data) {
261*4882a593Smuzhiyun 		/* widevine keybox */
262*4882a593Smuzhiyun 		TEEC_UUID widevine_uuid = { 0x1b484ea5, 0x698b, 0x4142,
263*4882a593Smuzhiyun 			{ 0x82, 0xb8, 0x3a, 0xcf, 0x16, 0xe9, 0x9e, 0x2a } };
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 		key_size = *(widevine_data + SIZE_OF_TAG);
266*4882a593Smuzhiyun 		data_size = *(widevine_data + SIZE_OF_TAG + sizeof(key_size));
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 		ret = rk_send_keybox_to_ta((uint8_t *)"widevine_keybox",
269*4882a593Smuzhiyun 					   sizeof("widevine_keybox"),
270*4882a593Smuzhiyun 					   widevine_uuid,
271*4882a593Smuzhiyun 					   widevine_data + SIZE_OF_TAG +
272*4882a593Smuzhiyun 					   sizeof(key_size) + sizeof(data_size),
273*4882a593Smuzhiyun 					   key_size,
274*4882a593Smuzhiyun 					   widevine_data + 12 + key_size,
275*4882a593Smuzhiyun 					   data_size);
276*4882a593Smuzhiyun 		if (ret == TEEC_SUCCESS) {
277*4882a593Smuzhiyun 			rc = 0;
278*4882a593Smuzhiyun 			printf("write widevine keybox to secure storage success\n");
279*4882a593Smuzhiyun 		} else {
280*4882a593Smuzhiyun 			rc = -EIO;
281*4882a593Smuzhiyun 			printf("write widevine keybox to secure storage fail\n");
282*4882a593Smuzhiyun 		}
283*4882a593Smuzhiyun 	} else if (attestation_data) {
284*4882a593Smuzhiyun 		/* attestation key */
285*4882a593Smuzhiyun 		atap_result ret;
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun 		ret = write_attestation_key_to_secure_storage(attestation_data,
288*4882a593Smuzhiyun 							      len);
289*4882a593Smuzhiyun 		if (ret == ATAP_RESULT_OK) {
290*4882a593Smuzhiyun 			rc = 0;
291*4882a593Smuzhiyun 			printf("write attestation key to secure storage success\n");
292*4882a593Smuzhiyun 		} else {
293*4882a593Smuzhiyun 			rc = -EIO;
294*4882a593Smuzhiyun 			printf("write attestation key to secure storage fail\n");
295*4882a593Smuzhiyun 		}
296*4882a593Smuzhiyun 	} else if (playready_sl30_data) {
297*4882a593Smuzhiyun 		/* PlayReady SL3000 root key */
298*4882a593Smuzhiyun 		uint32_t ret;
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 		data_size = *(playready_sl30_data + SIZE_OF_TAG);
301*4882a593Smuzhiyun 		ret = write_to_security_storage(is_use_rpmb,
302*4882a593Smuzhiyun 						(uint8_t *)"PlayReady_SL3000",
303*4882a593Smuzhiyun 						sizeof("PlayReady_SL3000"),
304*4882a593Smuzhiyun 						playready_sl30_data +
305*4882a593Smuzhiyun 						SIZE_OF_TAG +sizeof(data_size),
306*4882a593Smuzhiyun 						data_size);
307*4882a593Smuzhiyun 		if (ret == TEEC_SUCCESS) {
308*4882a593Smuzhiyun 			rc = 0;
309*4882a593Smuzhiyun 			printf("write PlayReady SL3000 root key to secure storage success\n");
310*4882a593Smuzhiyun 		} else {
311*4882a593Smuzhiyun 			rc = -EIO;
312*4882a593Smuzhiyun 			printf("write PlayReady SL3000 root key to secure storage fail\n");
313*4882a593Smuzhiyun 		}
314*4882a593Smuzhiyun 	}
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	/* write all data to secure storage for readback check */
317*4882a593Smuzhiyun 	if (!rc) {
318*4882a593Smuzhiyun 		uint32_t ret;
319*4882a593Smuzhiyun 		uint8_t *raw_data = malloc(len + sizeof(uint32_t));
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 		/* add raw_data_len(4 byte) in begin of raw_data */
322*4882a593Smuzhiyun 		memcpy(raw_data, &len, sizeof(uint32_t));
323*4882a593Smuzhiyun 		memcpy((raw_data + sizeof(uint32_t)), received_data, len);
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 		ret = write_to_security_storage(is_use_rpmb,
326*4882a593Smuzhiyun 						(uint8_t *)"raw_data",
327*4882a593Smuzhiyun 						sizeof("raw_data"),
328*4882a593Smuzhiyun 						raw_data,
329*4882a593Smuzhiyun 						len + sizeof(uint32_t));
330*4882a593Smuzhiyun 		if (ret == TEEC_SUCCESS)
331*4882a593Smuzhiyun 			rc = 0;
332*4882a593Smuzhiyun 		else
333*4882a593Smuzhiyun 			rc = -EIO;
334*4882a593Smuzhiyun 		free(raw_data);
335*4882a593Smuzhiyun 	}
336*4882a593Smuzhiyun 	return rc;
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun 
read_raw_data_from_secure_storage(uint8_t * data,uint32_t data_size)339*4882a593Smuzhiyun uint32_t read_raw_data_from_secure_storage(uint8_t *data, uint32_t data_size)
340*4882a593Smuzhiyun {
341*4882a593Smuzhiyun 	uint32_t rc;
342*4882a593Smuzhiyun 	uint32_t key_size;
343*4882a593Smuzhiyun 	uint8_t *read_data = malloc(1024 * 40);
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	rc = read_from_keymaster((uint8_t *)"raw_data", sizeof("raw_data"),
346*4882a593Smuzhiyun 				 read_data, data_size);
347*4882a593Smuzhiyun 	if (rc != TEEC_SUCCESS)
348*4882a593Smuzhiyun 		return 0;
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	memcpy(&key_size, read_data, sizeof(uint32_t));
351*4882a593Smuzhiyun 	memcpy(data, read_data + sizeof(uint32_t), key_size);
352*4882a593Smuzhiyun 	rc = key_size;
353*4882a593Smuzhiyun 	free(read_data);
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 	return rc;
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun 
new_strstr(const char * s1,const char * s2,uint32_t l1)358*4882a593Smuzhiyun char *new_strstr(const char *s1, const char *s2, uint32_t l1)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun 	uint32_t l2;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 	l2 = strlen(s2);
363*4882a593Smuzhiyun 	if (!l2)
364*4882a593Smuzhiyun 		return (char *)s1;
365*4882a593Smuzhiyun 	while (l1 >= l2) {
366*4882a593Smuzhiyun 		l1--;
367*4882a593Smuzhiyun 		if (!memcmp(s1, s2, l2))
368*4882a593Smuzhiyun 			return (char *)s1;
369*4882a593Smuzhiyun 		s1++;
370*4882a593Smuzhiyun 	}
371*4882a593Smuzhiyun 	return NULL;
372*4882a593Smuzhiyun }
373