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