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