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