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 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 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 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 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