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