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 133 if (memcmp(received_data, WIDEVINE_TAG, SIZE_OF_TAG) == 0) { 134 /* widevine keybox */ 135 TEEC_UUID widevine_uuid = { 0x1b484ea5, 0x698b, 0x4142, 136 { 0x82, 0xb8, 0x3a, 0xcf, 0x16, 0xe9, 0x9e, 0x2a } }; 137 138 key_size = *(received_data + SIZE_OF_TAG); 139 data_size = *(received_data + SIZE_OF_TAG + sizeof(key_size)); 140 141 ret = rk_send_keybox_to_ta((uint8_t *)"widevine_keybox", 142 sizeof("widevine_keybox"), 143 widevine_uuid, 144 received_data + SIZE_OF_TAG + 145 sizeof(key_size) + sizeof(data_size), 146 key_size, 147 received_data + 12 + key_size, 148 data_size); 149 if (ret == TEEC_SUCCESS) { 150 rc = 0; 151 printf("write widevine keybox to secure storage success\n"); 152 } else { 153 rc = -EIO; 154 printf("write widevine keybox to secure storage fail\n"); 155 } 156 } else if (memcmp(received_data, ATTESTATION_TAG, SIZE_OF_TAG) == 0) { 157 /* attestation key */ 158 atap_result ret; 159 160 ret = write_attestation_key_to_secure_storage(received_data, len); 161 if (ret == ATAP_RESULT_OK) { 162 rc = 0; 163 printf("write attestation key to secure storage success\n"); 164 } else { 165 rc = -EIO; 166 printf("write attestation key to secure storage fail\n"); 167 } 168 } else if (memcmp(received_data, PLAYREADY30_TAG, SIZE_OF_TAG) == 0) { 169 /* PlayReady SL3000 root key */ 170 uint32_t ret; 171 172 data_size = *(received_data + SIZE_OF_TAG); 173 ret = write_to_keymaster((uint8_t *)"PlayReady_SL3000", 174 sizeof("PlayReady_SL3000"), 175 received_data + SIZE_OF_TAG + 176 sizeof(data_size), 177 data_size); 178 if (ret == TEEC_SUCCESS) { 179 rc = 0; 180 printf("write PlayReady SL3000 root key to secure storage success\n"); 181 } else { 182 rc = -EIO; 183 printf("write PlayReady SL3000 root key to secure storage fail\n"); 184 } 185 } 186 187 /* write all data to secure storage for readback check */ 188 if (!rc) { 189 uint32_t ret; 190 191 ret = write_to_keymaster((uint8_t *)"raw_data", 192 sizeof("raw_data"), 193 received_data, len); 194 if (ret == TEEC_SUCCESS) 195 rc = 0; 196 else 197 rc = -EIO; 198 } 199 return rc; 200 } 201 202 uint32_t read_raw_data_from_secure_storage(uint8_t *data, uint32_t data_size) 203 { 204 uint32_t rc; 205 206 rc = read_from_keymaster((uint8_t *)"raw_data", sizeof("raw_data"), 207 data, data_size - SIZE_OF_USB_CMD); 208 if (rc != TEEC_SUCCESS) 209 return 0; 210 rc = data_size - SIZE_OF_USB_CMD; 211 212 return rc; 213 } 214