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
read_from_keymaster(uint8_t * filename,uint32_t filename_size,uint8_t * data,uint32_t size)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
write_to_keymaster(uint8_t * filename,uint32_t filename_size,uint8_t * data,uint32_t data_size)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
trusty_write_oem_unlock(uint8_t unlock)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
trusty_read_oem_unlock(uint8_t * unlock)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