xref: /rk3399_rockchip-uboot/common/write_keybox.c (revision 2ba7147f8008e675b31a0a5c13b8366431ea09ae)
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	SIZE_OF_USB_CMD	8
19 #define	BOOT_FROM_EMMC	(1 << 1)
20 #define	WIDEVINE_TAG	"KBOX"
21 #define	ATTESTATION_TAG	"ATTE"
22 #define PLAYREADY30_TAG	"SL30"
23 
24 uint32_t rk_send_keybox_to_ta(uint8_t *filename, uint32_t filename_size,
25 			      TEEC_UUID uuid,
26 			      uint8_t *key, uint32_t key_size,
27 			      uint8_t *data, uint32_t data_size)
28 {
29 	uint32_t ErrorOrigin;
30 	TEEC_Result TeecResult;
31 	TEEC_Context TeecContext;
32 	TEEC_Session TeecSession;
33 	TEEC_UUID *TeecUuid = &uuid;
34 	TEEC_Operation TeecOperation = {0};
35 	TEEC_SharedMemory SharedMem0 = {0};
36 	TEEC_SharedMemory SharedMem1 = {0};
37 	TEEC_SharedMemory SharedMem2 = {0};
38 	struct blk_desc *dev_desc;
39 
40 	dev_desc = rockchip_get_bootdev();
41 	if (!dev_desc) {
42 		printf("%s: dev_desc is NULL!\n", __func__);
43 		return -TEEC_ERROR_GENERIC;
44 	}
45 
46 	TeecResult = OpteeClientApiLibInitialize();
47 	if (TeecResult != TEEC_SUCCESS)
48 		return TeecResult;
49 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
50 	if (TeecResult != TEEC_SUCCESS)
51 		return TeecResult;
52 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
53 						    TEEC_NONE,
54 						    TEEC_NONE,
55 						    TEEC_NONE);
56 
57 	/* 0 nand or emmc "security" partition , 1 rpmb */
58 	TeecOperation.params[0].value.a =
59 		(dev_desc->if_type == IF_TYPE_MMC) ? 1 : 0;
60 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
61 	TeecOperation.params[0].value.a = 0;
62 #endif
63 	TeecResult = TEEC_OpenSession(&TeecContext,
64 				      &TeecSession,
65 				      TeecUuid,
66 				      TEEC_LOGIN_PUBLIC,
67 				      NULL,
68 				      &TeecOperation,
69 				      &ErrorOrigin);
70 	if (TeecResult != TEEC_SUCCESS)
71 		return TeecResult;
72 
73 	SharedMem0.size = filename_size;
74 	SharedMem0.flags = 0;
75 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
76 	if (TeecResult != TEEC_SUCCESS)
77 		return TeecResult;
78 	memcpy(SharedMem0.buffer, filename, SharedMem0.size);
79 
80 	SharedMem1.size = key_size;
81 	SharedMem1.flags = 0;
82 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem1);
83 	if (TeecResult != TEEC_SUCCESS)
84 		return TeecResult;
85 	memcpy(SharedMem1.buffer, key, SharedMem1.size);
86 
87 	SharedMem2.size = data_size;
88 	SharedMem2.flags = 0;
89 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem2);
90 	if (TeecResult != TEEC_SUCCESS)
91 		return TeecResult;
92 	memcpy(SharedMem2.buffer, data, SharedMem2.size);
93 
94 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
95 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
96 	TeecOperation.params[1].tmpref.buffer = SharedMem1.buffer;
97 	TeecOperation.params[1].tmpref.size = SharedMem1.size;
98 	TeecOperation.params[2].tmpref.buffer = SharedMem2.buffer;
99 	TeecOperation.params[2].tmpref.size = SharedMem2.size;
100 
101 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
102 						    TEEC_MEMREF_TEMP_INPUT,
103 						    TEEC_MEMREF_TEMP_INOUT,
104 						    TEEC_NONE);
105 
106 	printf("write keybox to secure storage\n");
107 	TeecResult = TEEC_InvokeCommand(&TeecSession,
108 					STORAGE_CMD_WRITE,
109 					&TeecOperation,
110 					&ErrorOrigin);
111 	if (TeecResult != TEEC_SUCCESS)
112 		printf("send data to TA failed with code 0x%x\n", TeecResult);
113 	else
114 		printf("send data to TA success with code 0x%x\n", TeecResult);
115 
116 	TEEC_ReleaseSharedMemory(&SharedMem0);
117 	TEEC_ReleaseSharedMemory(&SharedMem1);
118 	TEEC_ReleaseSharedMemory(&SharedMem2);
119 
120 	TEEC_CloseSession(&TeecSession);
121 	TEEC_FinalizeContext(&TeecContext);
122 
123 	return TeecResult;
124 }
125 
126 uint32_t write_keybox_to_secure_storage(uint8_t *received_data, uint32_t len)
127 {
128 	uint32_t key_size;
129 	uint32_t data_size;
130 	int rc = 0;
131 	TEEC_Result ret;
132 
133 	if (memcmp(received_data, WIDEVINE_TAG, SIZE_OF_TAG) == 0) {
134 		/* widevine keybox */
135 		TEEC_UUID widevine_uuid = { 0x1b484ea5, 0x698b, 0x4142,
136 			{ 0x82, 0xb8, 0x3a, 0xcf, 0x16, 0xe9, 0x9e, 0x2a } };
137 
138 		key_size = *(received_data + SIZE_OF_TAG);
139 		data_size = *(received_data + SIZE_OF_TAG + sizeof(key_size));
140 
141 		ret = rk_send_keybox_to_ta((uint8_t *)"widevine_keybox",
142 					   sizeof("widevine_keybox"),
143 					   widevine_uuid,
144 					   received_data + SIZE_OF_TAG +
145 					   sizeof(key_size) + sizeof(data_size),
146 					   key_size,
147 					   received_data + 12 + key_size,
148 					   data_size);
149 		if (ret == TEEC_SUCCESS) {
150 			rc = 0;
151 			printf("write widevine keybox to secure storage success\n");
152 		} else {
153 			rc = -EIO;
154 			printf("write widevine keybox to secure storage fail\n");
155 		}
156 	} else if (memcmp(received_data, ATTESTATION_TAG, SIZE_OF_TAG) == 0) {
157 		/* attestation key */
158 		atap_result ret;
159 
160 		ret = write_attestation_key_to_secure_storage(received_data, len);
161 		if (ret == ATAP_RESULT_OK) {
162 			rc = 0;
163 			printf("write attestation key to secure storage success\n");
164 		} else {
165 			rc = -EIO;
166 			printf("write attestation key to secure storage fail\n");
167 		}
168 	} else if (memcmp(received_data, PLAYREADY30_TAG, SIZE_OF_TAG) == 0) {
169 		/* PlayReady SL3000 root key */
170 		uint32_t ret;
171 
172 		data_size = *(received_data + SIZE_OF_TAG);
173 		ret = write_to_keymaster((uint8_t *)"PlayReady_SL3000",
174 					 sizeof("PlayReady_SL3000"),
175 					 received_data + SIZE_OF_TAG +
176 					 sizeof(data_size),
177 					 data_size);
178 		if (ret == TEEC_SUCCESS) {
179 			rc = 0;
180 			printf("write PlayReady SL3000 root key to secure storage success\n");
181 		} else {
182 			rc = -EIO;
183 			printf("write PlayReady SL3000 root key to secure storage fail\n");
184 		}
185 	}
186 
187 	/* write all data to secure storage for readback check */
188 	if (!rc) {
189 		uint32_t ret;
190 
191 		ret = write_to_keymaster((uint8_t *)"raw_data",
192 					 sizeof("raw_data"),
193 					 received_data, len);
194 		if (ret == TEEC_SUCCESS)
195 			rc = 0;
196 		else
197 			rc = -EIO;
198 	}
199 	return rc;
200 }
201 
202 uint32_t read_raw_data_from_secure_storage(uint8_t *data, uint32_t data_size)
203 {
204 	uint32_t rc;
205 
206 	rc = read_from_keymaster((uint8_t *)"raw_data", sizeof("raw_data"),
207 				 data, data_size - SIZE_OF_USB_CMD);
208 	if (rc != TEEC_SUCCESS)
209 		return 0;
210 	rc = data_size - SIZE_OF_USB_CMD;
211 
212 	return rc;
213 }
214