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