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