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 TeecOperation.params[0].value.a =
53 (dev_desc->if_type == IF_TYPE_MMC)
54 ? 1 : 0;
55 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
56 TeecOperation.params[0].value.a = 0;
57 #endif
58
59 TeecResult = TEEC_OpenSession(&TeecContext,
60 &TeecSession,
61 TeecUuid,
62 TEEC_LOGIN_PUBLIC,
63 NULL,
64 &TeecOperation,
65 &ErrorOrigin);
66
67 TEEC_SharedMemory SharedMem0 = {0};
68
69 SharedMem0.size = filename_size;
70 SharedMem0.flags = 0;
71
72 TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
73
74 memcpy(SharedMem0.buffer, filename, SharedMem0.size);
75
76 TEEC_SharedMemory SharedMem1 = {0};
77
78 SharedMem1.size = size;
79 SharedMem1.flags = 0;
80
81 TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem1);
82
83 TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
84 TeecOperation.params[0].tmpref.size = SharedMem0.size;
85
86 TeecOperation.params[1].tmpref.buffer = SharedMem1.buffer;
87 TeecOperation.params[1].tmpref.size = SharedMem1.size;
88
89 TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
90 TEEC_MEMREF_TEMP_INOUT,
91 TEEC_NONE,
92 TEEC_NONE);
93
94 TeecResult = TEEC_InvokeCommand(&TeecSession,
95 0,
96 &TeecOperation,
97 &ErrorOrigin);
98
99 if (TeecResult == TEEC_SUCCESS)
100 memcpy(data, SharedMem1.buffer, SharedMem1.size);
101 TEEC_ReleaseSharedMemory(&SharedMem0);
102 TEEC_ReleaseSharedMemory(&SharedMem1);
103 TEEC_CloseSession(&TeecSession);
104 TEEC_FinalizeContext(&TeecContext);
105 debug("read_from_keymaster end\n");
106
107 return TeecResult;
108 }
109
write_to_keymaster(uint8_t * filename,uint32_t filename_size,uint8_t * data,uint32_t data_size)110 TEEC_Result write_to_keymaster(uint8_t *filename,
111 uint32_t filename_size,
112 uint8_t *data,
113 uint32_t data_size)
114 {
115 TEEC_Result TeecResult;
116 TEEC_Context TeecContext;
117 TEEC_Session TeecSession;
118 uint32_t ErrorOrigin;
119
120 TEEC_UUID tempuuid = { 0x1b484ea5,
121 0x698b,
122 0x4142,
123 { 0x82, 0xb8, 0x3a,
124 0xcf, 0x16, 0xe9,
125 0x9e, 0x2a } };
126
127 TEEC_UUID *TeecUuid = &tempuuid;
128 TEEC_Operation TeecOperation = {0};
129 struct blk_desc *dev_desc;
130
131 dev_desc = rockchip_get_bootdev();
132 if (!dev_desc) {
133 printf("%s: dev_desc is NULL!\n", __func__);
134 return -TEEC_ERROR_GENERIC;
135 }
136
137 debug("write_to_keymaster\n");
138 OpteeClientApiLibInitialize();
139
140 TeecResult = TEEC_InitializeContext(NULL, &TeecContext);
141
142 TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
143 TEEC_NONE,
144 TEEC_NONE,
145 TEEC_NONE);
146
147 /*0 nand or emmc "security" partition , 1 rpmb*/
148 TeecOperation.params[0].value.a = (dev_desc->if_type == IF_TYPE_MMC)
149 ? 1 : 0;
150
151 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION
152 TeecOperation.params[0].value.a = 0;
153 #endif
154
155 TeecResult = TEEC_OpenSession(&TeecContext,
156 &TeecSession,
157 TeecUuid,
158 TEEC_LOGIN_PUBLIC,
159
160 NULL, &TeecOperation, &ErrorOrigin);
161
162 TEEC_SharedMemory SharedMem0 = {0};
163
164 SharedMem0.size = filename_size;
165 SharedMem0.flags = 0;
166
167 TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0);
168
169 memcpy(SharedMem0.buffer, filename, SharedMem0.size);
170
171 TEEC_SharedMemory SharedMem1 = {0};
172
173 SharedMem1.size = data_size;
174 SharedMem1.flags = 0;
175
176 TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem1);
177
178 memcpy(SharedMem1.buffer, data, SharedMem1.size);
179
180 TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer;
181 TeecOperation.params[0].tmpref.size = SharedMem0.size;
182
183 TeecOperation.params[1].tmpref.buffer = SharedMem1.buffer;
184 TeecOperation.params[1].tmpref.size = SharedMem1.size;
185
186 TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
187 TEEC_MEMREF_TEMP_INOUT,
188 TEEC_NONE,
189 TEEC_NONE);
190
191 TeecResult = TEEC_InvokeCommand(&TeecSession,
192 1,
193 &TeecOperation,
194 &ErrorOrigin);
195
196 TEEC_ReleaseSharedMemory(&SharedMem0);
197 TEEC_ReleaseSharedMemory(&SharedMem1);
198 TEEC_CloseSession(&TeecSession);
199 TEEC_FinalizeContext(&TeecContext);
200 debug("write_to_keymaster end\n");
201 debug("TeecResult %x\n", TeecResult);
202
203 return TeecResult;
204 }
205
trusty_write_oem_unlock(uint8_t unlock)206 TEEC_Result trusty_write_oem_unlock(uint8_t unlock)
207 {
208 char *file = "oem.unlock";
209 TEEC_Result ret;
210
211 ret = write_to_keymaster((uint8_t *)file,
212 strlen(file),
213 (uint8_t *)&unlock,
214 1);
215 return ret;
216 }
217
trusty_read_oem_unlock(uint8_t * unlock)218 TEEC_Result trusty_read_oem_unlock(uint8_t *unlock)
219 {
220 char *file = "oem.unlock";
221 TEEC_Result ret;
222
223 ret = read_from_keymaster((uint8_t *)file,
224 strlen(file),
225 unlock,
226 1);
227
228 if (ret == TEE_ERROR_ITEM_NOT_FOUND) {
229 debug("init oem unlock status 0");
230 ret = trusty_write_oem_unlock(0);
231 }
232
233 return ret;
234 }
235