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 BOOT_FROM_EMMC (1 << 1) 19 #define WIDEVINE_TAG "KBOX" 20 #define ATTESTATION_TAG "ATTE" 21 #define PLAYREADY30_TAG "SL30" 22 23 uint32_t rk_send_keybox_to_ta(uint8_t *filename, uint32_t filename_size, 24 TEEC_UUID uuid, 25 uint8_t *key, uint32_t key_size, 26 uint8_t *data, uint32_t data_size) 27 { 28 uint32_t ErrorOrigin; 29 TEEC_Result TeecResult; 30 TEEC_Context TeecContext; 31 TEEC_Session TeecSession; 32 TEEC_UUID *TeecUuid = &uuid; 33 TEEC_Operation TeecOperation = {0}; 34 TEEC_SharedMemory SharedMem0 = {0}; 35 TEEC_SharedMemory SharedMem1 = {0}; 36 TEEC_SharedMemory SharedMem2 = {0}; 37 struct blk_desc *dev_desc; 38 39 dev_desc = rockchip_get_bootdev(); 40 if (!dev_desc) { 41 printf("%s: dev_desc is NULL!\n", __func__); 42 return -TEEC_ERROR_GENERIC; 43 } 44 45 TeecResult = OpteeClientApiLibInitialize(); 46 if (TeecResult != TEEC_SUCCESS) 47 return TeecResult; 48 TeecResult = TEEC_InitializeContext(NULL, &TeecContext); 49 if (TeecResult != TEEC_SUCCESS) 50 return TeecResult; 51 TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, 52 TEEC_NONE, 53 TEEC_NONE, 54 TEEC_NONE); 55 56 /* 0 nand or emmc "security" partition , 1 rpmb */ 57 TeecOperation.params[0].value.a = 58 (dev_desc->if_type == IF_TYPE_MMC) ? 1 : 0; 59 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION 60 TeecOperation.params[0].value.a = 0; 61 #endif 62 TeecResult = TEEC_OpenSession(&TeecContext, 63 &TeecSession, 64 TeecUuid, 65 TEEC_LOGIN_PUBLIC, 66 NULL, 67 &TeecOperation, 68 &ErrorOrigin); 69 if (TeecResult != TEEC_SUCCESS) 70 return TeecResult; 71 72 SharedMem0.size = filename_size; 73 SharedMem0.flags = 0; 74 TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem0); 75 if (TeecResult != TEEC_SUCCESS) 76 return TeecResult; 77 memcpy(SharedMem0.buffer, filename, SharedMem0.size); 78 79 SharedMem1.size = key_size; 80 SharedMem1.flags = 0; 81 TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem1); 82 if (TeecResult != TEEC_SUCCESS) 83 return TeecResult; 84 memcpy(SharedMem1.buffer, key, SharedMem1.size); 85 86 SharedMem2.size = data_size; 87 SharedMem2.flags = 0; 88 TeecResult = TEEC_AllocateSharedMemory(&TeecContext, &SharedMem2); 89 if (TeecResult != TEEC_SUCCESS) 90 return TeecResult; 91 memcpy(SharedMem2.buffer, data, SharedMem2.size); 92 93 TeecOperation.params[0].tmpref.buffer = SharedMem0.buffer; 94 TeecOperation.params[0].tmpref.size = SharedMem0.size; 95 TeecOperation.params[1].tmpref.buffer = SharedMem1.buffer; 96 TeecOperation.params[1].tmpref.size = SharedMem1.size; 97 TeecOperation.params[2].tmpref.buffer = SharedMem2.buffer; 98 TeecOperation.params[2].tmpref.size = SharedMem2.size; 99 100 TeecOperation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, 101 TEEC_MEMREF_TEMP_INPUT, 102 TEEC_MEMREF_TEMP_INOUT, 103 TEEC_NONE); 104 105 printf("write keybox to secure storage\n"); 106 TeecResult = TEEC_InvokeCommand(&TeecSession, 107 STORAGE_CMD_WRITE, 108 &TeecOperation, 109 &ErrorOrigin); 110 if (TeecResult != TEEC_SUCCESS) 111 printf("send data to TA failed with code 0x%x\n", TeecResult); 112 else 113 printf("send data to TA success with code 0x%x\n", TeecResult); 114 115 TEEC_ReleaseSharedMemory(&SharedMem0); 116 TEEC_ReleaseSharedMemory(&SharedMem1); 117 TEEC_ReleaseSharedMemory(&SharedMem2); 118 119 TEEC_CloseSession(&TeecSession); 120 TEEC_FinalizeContext(&TeecContext); 121 122 return TeecResult; 123 } 124 125 uint32_t write_keybox_to_secure_storage(uint8_t *received_data, uint32_t len) 126 { 127 uint8_t *widevine_data; 128 uint8_t *attestation_data; 129 uint8_t *playready_sl30_data; 130 uint32_t key_size; 131 uint32_t data_size; 132 int rc = 0; 133 TEEC_Result ret; 134 struct blk_desc *dev_desc; 135 uint8_t is_use_rpmb; 136 137 dev_desc = rockchip_get_bootdev(); 138 if (!dev_desc) { 139 printf("%s: dev_desc is NULL!\n", __func__); 140 return -EIO; 141 } 142 is_use_rpmb = (dev_desc->if_type == IF_TYPE_MMC) ? 1 : 0; 143 #ifdef CONFIG_OPTEE_ALWAYS_USE_SECURITY_PARTITION 144 is_use_rpmb = 0; 145 #endif 146 if (is_use_rpmb) 147 printf("I will write key to rpmb\n"); 148 else 149 printf("I will write key to security partition"); 150 rc = write_to_keymaster((uint8_t *)"security_partition", 151 sizeof("security_partition"), 152 &is_use_rpmb, sizeof(is_use_rpmb)); 153 if (rc) 154 return -EIO; 155 156 widevine_data = (uint8_t *)new_strstr((char *)received_data, 157 WIDEVINE_TAG, len); 158 attestation_data = (uint8_t *)new_strstr((char *)received_data, 159 ATTESTATION_TAG, len); 160 playready_sl30_data = (uint8_t *)new_strstr((char *)received_data, 161 PLAYREADY30_TAG, len); 162 if (widevine_data) { 163 /* widevine keybox */ 164 TEEC_UUID widevine_uuid = { 0x1b484ea5, 0x698b, 0x4142, 165 { 0x82, 0xb8, 0x3a, 0xcf, 0x16, 0xe9, 0x9e, 0x2a } }; 166 167 key_size = *(widevine_data + SIZE_OF_TAG); 168 data_size = *(widevine_data + SIZE_OF_TAG + sizeof(key_size)); 169 170 ret = rk_send_keybox_to_ta((uint8_t *)"widevine_keybox", 171 sizeof("widevine_keybox"), 172 widevine_uuid, 173 widevine_data + SIZE_OF_TAG + 174 sizeof(key_size) + sizeof(data_size), 175 key_size, 176 widevine_data + 12 + key_size, 177 data_size); 178 if (ret == TEEC_SUCCESS) { 179 rc = 0; 180 printf("write widevine keybox to secure storage success\n"); 181 } else { 182 rc = -EIO; 183 printf("write widevine keybox to secure storage fail\n"); 184 } 185 } else if (attestation_data) { 186 /* attestation key */ 187 atap_result ret; 188 189 ret = write_attestation_key_to_secure_storage(attestation_data, 190 len); 191 if (ret == ATAP_RESULT_OK) { 192 rc = 0; 193 printf("write attestation key to secure storage success\n"); 194 } else { 195 rc = -EIO; 196 printf("write attestation key to secure storage fail\n"); 197 } 198 } else if (playready_sl30_data) { 199 /* PlayReady SL3000 root key */ 200 uint32_t ret; 201 202 data_size = *(playready_sl30_data + SIZE_OF_TAG); 203 ret = write_to_keymaster((uint8_t *)"PlayReady_SL3000", 204 sizeof("PlayReady_SL3000"), 205 playready_sl30_data + SIZE_OF_TAG + 206 sizeof(data_size), 207 data_size); 208 if (ret == TEEC_SUCCESS) { 209 rc = 0; 210 printf("write PlayReady SL3000 root key to secure storage success\n"); 211 } else { 212 rc = -EIO; 213 printf("write PlayReady SL3000 root key to secure storage fail\n"); 214 } 215 } 216 217 /* write all data to secure storage for readback check */ 218 if (!rc) { 219 uint32_t ret; 220 uint8_t *raw_data = malloc(len + sizeof(uint32_t)); 221 222 /* add raw_data_len(4 byte) in begin of raw_data */ 223 memcpy(raw_data, &len, sizeof(uint32_t)); 224 memcpy((raw_data + sizeof(uint32_t)), received_data, len); 225 226 ret = write_to_keymaster((uint8_t *)"raw_data", 227 sizeof("raw_data"), 228 raw_data, len + sizeof(uint32_t)); 229 if (ret == TEEC_SUCCESS) 230 rc = 0; 231 else 232 rc = -EIO; 233 free(raw_data); 234 } 235 return rc; 236 } 237 238 uint32_t read_raw_data_from_secure_storage(uint8_t *data, uint32_t data_size) 239 { 240 uint32_t rc; 241 uint32_t key_size; 242 uint8_t *read_data = malloc(1024 * 40); 243 244 rc = read_from_keymaster((uint8_t *)"raw_data", sizeof("raw_data"), 245 read_data, data_size); 246 if (rc != TEEC_SUCCESS) 247 return 0; 248 249 memcpy(&key_size, read_data, sizeof(uint32_t)); 250 memcpy(data, read_data + sizeof(uint32_t), key_size); 251 rc = key_size; 252 free(read_data); 253 254 return rc; 255 } 256 257 char *new_strstr(const char *s1, const char *s2, uint32_t l1) 258 { 259 uint32_t l2; 260 261 l2 = strlen(s2); 262 if (!l2) 263 return (char *)s1; 264 while (l1 >= l2) { 265 l1--; 266 if (!memcmp(s1, s2, l2)) 267 return (char *)s1; 268 s1++; 269 } 270 return NULL; 271 } 272