xref: /rk3399_rockchip-uboot/common/keymaster.c (revision f2098163f6f9598107fd08b0b97118d1c71a4bf6)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4  */
5 
6 #include <keymaster.h>
7 #include <common.h>
8 #include <boot_rkimg.h>
9 #include <malloc.h>
10 
11 #include <optee_include/OpteeClientApiLib.h>
12 #include <optee_include/tee_client_api.h>
13 #include <optee_include/tee_api_defines.h>
14 
15 TEEC_Result read_from_keymaster(uint8_t *filename,
16 				uint32_t filename_size,
17 				uint8_t *data,
18 				uint32_t size)
19 {
20 	TEEC_Result TeecResult;
21 	TEEC_Context TeecContext;
22 	TEEC_Session TeecSession;
23 	uint32_t ErrorOrigin;
24 	TEEC_UUID tempuuid = { 0x1b484ea5,
25 			       0x698b,
26 			       0x4142,
27 			       { 0x82, 0xb8, 0x3a,
28 				 0xcf, 0x16, 0xe9,
29 				 0x9e, 0x2a } };
30 
31 	TEEC_UUID *TeecUuid = &tempuuid;
32 	TEEC_Operation TeecOperation = {0};
33 	struct blk_desc *dev_desc;
34 
35 	dev_desc = rockchip_get_bootdev();
36 	if (!dev_desc) {
37 		printf("%s: dev_desc is NULL!\n", __func__);
38 		return -TEEC_ERROR_GENERIC;
39 	}
40 
41 	debug("read_from_keymaster start\n");
42 	OpteeClientApiLibInitialize();
43 
44 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
45 
46 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
47 						    TEEC_NONE,
48 						    TEEC_NONE,
49 						    TEEC_NONE);
50 
51 	/*0 nand or emmc "security" partition , 1 rpmb*/
52 	if (dev_desc->if_type == IF_TYPE_MMC && dev_desc->devnum == 0)//emmc
53 		TeecOperation.params[0].value.a = 1;
54 	else if (dev_desc->if_type == IF_TYPE_SCSI)//ufs
55 		TeecOperation.params[0].value.a = 1;
56 	else
57 		TeecOperation.params[0].value.a = 0;
58 
59 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
60 	TeecOperation.params[0].value.a = 0;
61 #endif
62 
63 	TeecResult = TEEC_OpenSession(&TeecContext,
64 				      &TeecSession,
65 				      TeecUuid,
66 				      TEEC_LOGIN_PUBLIC,
67 				      NULL,
68 				      &TeecOperation,
69 				      &ErrorOrigin);
70 
71 	TEEC_SharedMemory SharedMem0 = {0};
72 
73 	SharedMem0.size = filename_size;
74 	SharedMem0.flags = 0;
75 
76 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
77 
78 	memcpy(SharedMem0.buffer, filename, SharedMem0.size);
79 
80 	TEEC_SharedMemory SharedMem1 = {0};
81 
82 	SharedMem1.size = size;
83 	SharedMem1.flags = 0;
84 
85 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem1);
86 
87 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
88 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
89 
90 	TeecOperation.params[1].tmpref.buffer = SharedMem1.buffer;
91 	TeecOperation.params[1].tmpref.size = SharedMem1.size;
92 
93 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
94 						    TEEC_MEMREF_TEMP_INOUT,
95 						    TEEC_NONE,
96 						    TEEC_NONE);
97 
98 	TeecResult = TEEC_InvokeCommand(&TeecSession,
99 					0,
100 					&TeecOperation,
101 					&ErrorOrigin);
102 
103 	if (TeecResult == TEEC_SUCCESS)
104 		memcpy(data, SharedMem1.buffer, SharedMem1.size);
105 	TEEC_ReleaseSharedMemory(&SharedMem0);
106 	TEEC_ReleaseSharedMemory(&SharedMem1);
107 	TEEC_CloseSession(&TeecSession);
108 	TEEC_FinalizeContext(&TeecContext);
109 	debug("read_from_keymaster end\n");
110 
111 	return TeecResult;
112 }
113 
114 TEEC_Result write_to_keymaster(uint8_t *filename,
115 			       uint32_t filename_size,
116 			       uint8_t *data,
117 			       uint32_t data_size)
118 {
119 	TEEC_Result TeecResult;
120 	TEEC_Context TeecContext;
121 	TEEC_Session TeecSession;
122 	uint32_t ErrorOrigin;
123 
124 	TEEC_UUID tempuuid = { 0x1b484ea5,
125 			       0x698b,
126 			       0x4142,
127 			       { 0x82, 0xb8, 0x3a,
128 				 0xcf, 0x16, 0xe9,
129 				 0x9e, 0x2a } };
130 
131 	TEEC_UUID *TeecUuid = &tempuuid;
132 	TEEC_Operation TeecOperation = {0};
133 	struct blk_desc *dev_desc;
134 
135 	dev_desc = rockchip_get_bootdev();
136 	if (!dev_desc) {
137 		printf("%s: dev_desc is NULL!\n", __func__);
138 		return -TEEC_ERROR_GENERIC;
139 	}
140 
141 	debug("write_to_keymaster\n");
142 	OpteeClientApiLibInitialize();
143 
144 	TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
145 
146 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
147 						    TEEC_NONE,
148 						    TEEC_NONE,
149 						    TEEC_NONE);
150 
151 	/*0 nand or emmc "security" partition , 1 rpmb*/
152 	if (dev_desc->if_type == IF_TYPE_MMC && dev_desc->devnum == 0)//emmc
153 		TeecOperation.params[0].value.a = 1;
154 	else if (dev_desc->if_type == IF_TYPE_SCSI)//ufs
155 		TeecOperation.params[0].value.a = 1;
156 	else
157 		TeecOperation.params[0].value.a = 0;
158 
159 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
160 	TeecOperation.params[0].value.a = 0;
161 #endif
162 
163 	TeecResult = TEEC_OpenSession(&TeecContext,
164 				      &TeecSession,
165 				      TeecUuid,
166 				      TEEC_LOGIN_PUBLIC,
167 
168 	NULL, &TeecOperation, &ErrorOrigin);
169 
170 	TEEC_SharedMemory SharedMem0 = {0};
171 
172 	SharedMem0.size = filename_size;
173 	SharedMem0.flags = 0;
174 
175 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
176 
177 	memcpy(SharedMem0.buffer, filename, SharedMem0.size);
178 
179 	TEEC_SharedMemory SharedMem1 = {0};
180 
181 	SharedMem1.size = data_size;
182 	SharedMem1.flags = 0;
183 
184 	TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem1);
185 
186 	memcpy(SharedMem1.buffer, data, SharedMem1.size);
187 
188 	TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
189 	TeecOperation.params[0].tmpref.size = SharedMem0.size;
190 
191 	TeecOperation.params[1].tmpref.buffer = SharedMem1.buffer;
192 	TeecOperation.params[1].tmpref.size = SharedMem1.size;
193 
194 	TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
195 						    TEEC_MEMREF_TEMP_INOUT,
196 						    TEEC_NONE,
197 						    TEEC_NONE);
198 
199 	TeecResult = TEEC_InvokeCommand(&TeecSession,
200 					1,
201 					&TeecOperation,
202 					&ErrorOrigin);
203 
204 	TEEC_ReleaseSharedMemory(&SharedMem0);
205 	TEEC_ReleaseSharedMemory(&SharedMem1);
206 	TEEC_CloseSession(&TeecSession);
207 	TEEC_FinalizeContext(&TeecContext);
208 	debug("write_to_keymaster end\n");
209 	debug("TeecResult %x\n", TeecResult);
210 
211 	return TeecResult;
212 }
213 
214 TEEC_Result trusty_write_oem_unlock(uint8_t unlock)
215 {
216 	char *file = "oem.unlock";
217 	TEEC_Result ret;
218 
219 	ret = write_to_keymaster((uint8_t *)file,
220 				 strlen(file),
221 				 (uint8_t *)&unlock,
222 				 1);
223 	return ret;
224 }
225 
226 TEEC_Result trusty_read_oem_unlock(uint8_t *unlock)
227 {
228 	char *file = "oem.unlock";
229 	TEEC_Result ret;
230 
231 	ret = read_from_keymaster((uint8_t *)file,
232 				   strlen(file),
233 				   unlock,
234 				   1);
235 
236 	if (ret == TEE_ERROR_ITEM_NOT_FOUND) {
237 		debug("init oem unlock status 0");
238 		ret = trusty_write_oem_unlock(0);
239 	}
240 
241 	return ret;
242 }
243