From 51e98c12184125a1aff24d63354448c1175c9e4b Mon Sep 17 00:00:00 2001 From: LVZE Date: Thu, 29 Jun 2023 07:53:40 +0000 Subject: [PATCH 1/2] add sdk case : tee_upgrade --- test/CA/tee_upgrade/Makefile | 15 ++ test/CA/tee_upgrade/upgrade.c | 290 ++++++++++++++++++++++++++ test/TA/tee_upgrade/CMakeLists.txt | 55 +++++ test/TA/tee_upgrade/config.cmake | 12 ++ test/TA/tee_upgrade/manifest.txt | 7 + test/TA/tee_upgrade/src/tee_decrypt.c | 260 +++++++++++++++++++++++ test/TA/tee_upgrade/src/tee_decrypt.h | 71 +++++++ test/TA/tee_upgrade/src/upgrade.c | 234 +++++++++++++++++++++ 8 files changed, 944 insertions(+) create mode 100644 test/CA/tee_upgrade/Makefile create mode 100644 test/CA/tee_upgrade/upgrade.c create mode 100644 test/TA/tee_upgrade/CMakeLists.txt create mode 100644 test/TA/tee_upgrade/config.cmake create mode 100644 test/TA/tee_upgrade/manifest.txt create mode 100644 test/TA/tee_upgrade/src/tee_decrypt.c create mode 100644 test/TA/tee_upgrade/src/tee_decrypt.h create mode 100644 test/TA/tee_upgrade/src/upgrade.c diff --git a/test/CA/tee_upgrade/Makefile b/test/CA/tee_upgrade/Makefile new file mode 100644 index 0000000..4e52a12 --- /dev/null +++ b/test/CA/tee_upgrade/Makefile @@ -0,0 +1,15 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. +obj-m := tee_upgrade.o +tee_upgrade-objs := upgrade.o + +EXTRA_CFLAGS += -I$(PWD)/../itrustee/platform/libhwsecurec/include/libhwsecurec -I$(PWD)/../iTrustee/platform/libhwsecurec/include + +KPATH := /usr/src/kernels +KDIR := $(KPATH)/$(shell ls $(KPATH)) + +EXTRA_CFLAGS += -I$(PWD)/../tzdriver + +all: + make -C $(KDIR) M=$(PWD) modules +clean: + -rm -vrf *.order *.symvers *.mod.c .tmp_version .*o.cmd *.o \ No newline at end of file diff --git a/test/CA/tee_upgrade/upgrade.c b/test/CA/tee_upgrade/upgrade.c new file mode 100644 index 0000000..e583285 --- /dev/null +++ b/test/CA/tee_upgrade/upgrade.c @@ -0,0 +1,290 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. + * Licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: C file template for CA + */ + +#include +#include +#include +#include "tee_client_api.h" +#include + +#define PART_IMAGE_LEN 0x100000 +#define UPGRADE_SEND_IMAGE_BEGIN 0xaa +#define UPGRADE_SEND_IMAGE_UPDATE 0xbb +#define UPGRADE_SEND_IMAGE_FINISH 0xcc +#define MAX_IMAGE_LENGTH 0x1000000 +#ifndef CONFIG_TEE_IMG_PATH +#define CONFIG_TEE_IMG_PATH "/var/itrustee/image/trustedcore.img" +#endif + +/* array index */ +#define ARRAY_INDEX2 2 +#define ARRAY_INDEX3 3 + +extern int tee_reboot(void); + +static int32_t teek_open_app_file(struct file *fp, char **file_buf, uint32_t total_img_len) +{ + loff_t pos = 0; + uint32_t read_size; + char *file_buffer = NULL; + + if (total_img_len == 0 || total_img_len > MAX_IMAGE_LENGTH) { + tloge("img len is invalied, len=%u\n", total_img_len); + return TEEC_ERROR_BAD_PARAMETERS; + } + + file_buffer = vmalloc(total_img_len); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)file_buffer)) { + tloge("alloc TA file buffer(size=%u) failed\n", total_img_len); + return TEEC_ERROR_GENERIC; + } + + read_size = (uint32_t)kernel_read(fp, file_buffer, total_img_len, &pos); + if (read_size != total_img_len) { + tloge("read ta file failed, read size/total size=%u/%u\n", read_size, total_img_len); + vfree(file_buffer); + return TEEC_ERROR_GENERIC; + } + + *file_buf = file_buffer; + + return TEEC_SUCCESS; +} + +static int32_t teek_read_app(const char *load_file, char **file_buf, uint32_t *file_len) +{ + int32_t ret; + struct file *fp = NULL; + + fp = file_open(load_file, O_RDONLY, 0); + if (!fp || IS_ERR(fp)) { + tloge("open file error, err = %ld\n", PTR_ERR(fp)); + return TEEC_ERROR_BAD_PARAMETERS; + } + + if (!fp->f_inode) { + tloge("node is NULL\n"); + filp_close(fp, 0); + return TEEC_ERROR_BAD_PARAMETERS; + } + + *file_len = (uint32_t)(fp->f_inode->i_size); + + ret = teek_open_app_file(fp, file_buf, *file_len); + if (ret != TEEC_SUCCESS) + tloge("do read app fail\n"); + + if (fp != NULL) { + filp_close(fp, 0); + fp = NULL; + } + + return ret; +} + +statc void teek_free_app(bool load_app_flag, char **file_buf) +{ + if (load_app_flag && file_buf != NULL && ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)(*file_buf))) { + vfree(*file_buf); + *file_buf = NULL; + } +} + +static int32_t teek_get_app(const char *ta_path, char ** file_buf, uint32_t *file_len) +{ + int32_t ret; + + if (!ta_path) + return TEEC_ERROR_BAD_PARAMETERS; + + if (!file_buf || !file_len) { + tloge("load app params invalid\n"); + return TEEC_ERROR_BAD_PARAMETERS; + } + + ret = teek_read_app(ta_path, file_buf, file_len); + if (ret != TEEC_SUCCESS) + tloge("teec load app error, err=%d\n", ret); + + return ret; +} + +static int send_image_begin(TEEC_Session *TEEC_Session, uint32_t image_length) +{ + uint32_t origin = 0; + TEEC_OpenSession operation = {0}; + int ret = 0; + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_VALUE_INPUT); + operation.params[ARRAY_INDEX3].value.a = image_length; + + ret = TEEK_InvokeCommand(TEEC_Session, UPGRADE_SEND_IMAGE_BEGIN, &operation, &origin); + if (ret != 0) { + tloge("TEEK_InvokeCommand failed\n"); + return -1; + } + return 0; +} + +static int send_image_update(TEEC_Session *tee_session, char *file_buf, uint32_t image_length) +{ + uint32_t origin = 0; + uint32_t idx = 0; + uint32_t left_len = image_length; + int ret = 0; + + TEEC_OpenSession operation = {0}; + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE); + + while (left_len > 0) { + uint32_t len = (left_len >= PART_IMAGE_LEN) ? PART_IMAGE_LEN : left_len; + operation.params[ARRAY_INDEX2].tmpref.buffer = file_buf + idx * PART_IMAGE_LEN; + operation.params[ARRAY_INDEX2].tmpref.size = len; + ret = TEEK_InvokeCommand(tee_session, UPGRADE_SEND_IMAGE_UPDATE, &operation, &origin); + if (ret != 0) { + tloge("send image update failed\n"); + return -1; + } + left_len -= len; + idx++; + } + return 0; +} + +static int send_image_finish(TEEC_Session *tee_session) +{ + uint32_t origin = 0; + int ret = 0; + TEEC_Operation operation = {0}; + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + + ret = TEEK_InvokeCommand(tee_session, UPGRADE_SEND_IMAGE_FINISH, &operation, &origin); + if (ret != 0) { + tloge("send image finish failed\n"); + return -1; + } + + return ret; +} + +static int get_new_tee_image(TEEC_Session *tee_session) +{ + char *file_buf = NULL; + uint32_t image_length = 0; + + int ret = teek_get_app(CONFIG_TEE_IMG_PATH, &file_buf, &image_length); + if (ret != 0) { + tloge("get new tee image failed, use origin tee\n"); + teek_free_app(true, &file_buf); + return -1; + } + + ret = send_image_begin(tee_session, image_length); + if (ret != 0) { + tloge("send image begin failed\n"); + teek_free_app(true, &file_buf); + return -1; + } + + ret = send_image_begin(tee_session, image_length); + if (ret != 0) { + tloge("send image begin failed\n"); + teek_free_app(true, &file_buf); + return -1; + } + + ret = send_image_update(tee_session, file_buf, image_length); + if (ret != 0) { + tloge("send image update failed\n"); + teek_free_app(true, &file_buf); + return -1; + } + + ret = send_image_finish(tee_session); + if (ret != 0) { + tloge("send image end failed\n"); + teek_free_app(true, &file_buf); + return -1; + } + + teek_free_app(true, &file_buf); + return 0; +} + +// 9ab6f960-54f3-4317-a8f7-e92ed12b6ae2.sec +static const TEEC_UUID g_tee_uuid = { + 0x9ab6f960U, 0x54f3, 0x4317, + { 0xa8, 0xf7, 0xe9, 0x2e, 0xd1, 0x2b, 0x6a, 0xe2 } +}; + +static int32_t __init upgrade_init(void) +{ + TEEC_Result ret; + TEEC_Context ctx; + TEEC_Operation operation = {0}; + TEEC_Session tee_session; + uint32_t origin = 0; + uint32_t root_id = 0; + + ret = TEEK_InitializeContext(NULL, &ctx); + if (ret != 0) { + tloge("initialize context failed\n"); + return -1; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT); + operation.params[ARRAY_INDEX2].tmpref.buffer = (void *)(&root_id); + operation.params[ARRAY_INDEX2].tmpref.size = sizeof(root_id); + operation.params[ARRAY_INDEX3].tmpref.buffer = (void *)("tee_upgrade"); + operation.params[ARRAY_INDEX3].tmpref.size = strlen("tee_upgrade") + 1; + + ctx.ta_path = (uint8_t *)("/var/itrustee/image/9ab6f960-54f3-4317-a8f7-e92ed12b6ae2.sec"); + ret = TEEK_OpenSession(&ctx, &tee_session, &g_tee_uuid, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret != 0) { + tloge("TEEK_OpenSession failed\n"); + TEEK_FinalizeContext(&ctx); + return -1; + } + + ret = get_new_tee_image(&tee_session); + if (ret != 0) { + TEEK_CloseSession(&tee_session); + TEEK_FinalizeContext(&ctx); + return -1; + } + + TEEK_CloseSession(&tee_session); + TEEK_FinalizeContext(&ctx); + ret = (TEEC_Result)tee_reboot(); + if (ret != TEEC_SUCCESS) + return -1; + tlogi("teeos upgrade done"); + return 0; +} + +static void __exit upgrade_exit(void) +{ + tlogi("remove upgrade ca\n"); +} + +module_init(upgrade_init); +module_exit(upgrade_exit); + +MODULE_AUTHOR("Huawei Tech. Co., Ltd."); +MODULE_DESCRIPTION("TEE UPGRADE"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("V1.0"); diff --git a/test/TA/tee_upgrade/CMakeLists.txt b/test/TA/tee_upgrade/CMakeLists.txt new file mode 100644 index 0000000..db4005e --- /dev/null +++ b/test/TA/tee_upgrade/CMakeLists.txt @@ -0,0 +1,55 @@ +# sdk cmake. +# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. +cmake_minimum_required(VERSION 3.16 FATAL_ERROR) + +project(tee_upgrade C) + +if (PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) + message(FATAL_ERROR "Forbid compiling in the source tree") +endif() + +set(DYN_LINK y) +set(USE_SMEE n) +set(USE_ENTRY_BINARY n) + +include(${CMAKE_CURRENT_SOURCE_DIR}/config.cmake) +include(${CMAKE_CURRENT_SOURCE_DIR}/../common.cmake) + +if ("${USE_ON_BIOS}" STREQUAL "y") + list(APPEND CFLAGS + -DUSEONBIOS + ) +endif() +set(DEVICE_INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR}/../../../hm-teeos/libs/teelib/libopenssl/openssl/include + ${CMAKE_CURRENT_SOURCE_DIR}/../../../hm-teeos/libs/teelib/libhuk/include +) +set(DIR_SRCS + src/tee_decrypt.c + src/upgrade.c +) + +set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) +set(CURRENT_TARGET_SO "combine") + +if ("${DYN_LINK}" STREQUAL "y") + add_library(${CURRENT_TARGET_SO} SHARED ${DIR_SRCS} ${DYN_LINK_C}) +else() + add_library(${CURRENT_TARGET_SO} SHARED ${DIR_SRCS}) +endif() + +target_include_directories(${CURRENT_TARGET_SO} PUBLIC ${COMMON_INCLUDES}) +target_include_directories(${CURRENT_TARGET_SO} PRIVATE ${DEVICE_INCLUDES}) + +set_source_files_properties(${DIR_SRCS} PROPERTIES COMPILE_FLAGS "-DCONFIG_AUTH_USERNAME") +target_compile_options(${CURRENT_TARGET_SO} PRIVATE ${CFLAGS}) + +target_link_options(${CURRENT_TARGET_SO} PRIVATE ${LDFLAGS}) + +add_custom_command( + TARGET ${CURRENT_TARGET_SO} POST_BUILD + COMMAND ${CMAKE_OBJCOPY} ${CMAKE_CURRENT_SOURCE_DIR}/libcombine.so + COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/../../sdk/build/tools/ta_entry_check.sh + ${CMAKE_READELF} ${CMAKE_CURRENT_SOURCE_DIR}/libcombine.so + ${USE_ENTRY_BINARY} ${DYN_LINK} ${TARGET_IS_ARM64} +) diff --git a/test/TA/tee_upgrade/config.cmake b/test/TA/tee_upgrade/config.cmake new file mode 100644 index 0000000..cb7b6b6 --- /dev/null +++ b/test/TA/tee_upgrade/config.cmake @@ -0,0 +1,12 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. +# +# API_LEVEL which indicates the GP API version of TA +# API_LEVEL=1 indicates GP 1.0 which is the current version of itrustee +# API_LEVEL=2 indicates GP 1.1.1 which is the current version of the partner +# API_LEVEL=3 indicates GP 1.2 which is the version we both going to support +# If no API_LEVEL is specified, API of GP 1.0 will be taked +set(CFLAGS -DAPI_LEVEL=1) +set(TARGET_IS_ARM64 y) +set(USE_ON_BIOS n) +set(ENABLE_LIBFUZZER n) +set(ENABLE_PROFILE n) diff --git a/test/TA/tee_upgrade/manifest.txt b/test/TA/tee_upgrade/manifest.txt new file mode 100644 index 0000000..d00cf25 --- /dev/null +++ b/test/TA/tee_upgrade/manifest.txt @@ -0,0 +1,7 @@ +gpd.ta.appID: 9ab6f960-54f3-4317-a8f7-e92ed12b6ae2 +gpd.ta.service_name: teeupgrade +gpd.ta.singleInstance: true +gpd.ta.multiSession: false +gpd.ta.instanceKeepAlive: false +gpd.ta.dataSize: 10485760 +gpd.ta.stackSize: 32768 diff --git a/test/TA/tee_upgrade/src/tee_decrypt.c b/test/TA/tee_upgrade/src/tee_decrypt.c new file mode 100644 index 0000000..5b65cdf --- /dev/null +++ b/test/TA/tee_upgrade/src/tee_decrypt.c @@ -0,0 +1,260 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. + * Licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: tee_upgrade tee_decrypt.c. + */ + +#include +#include +#include +#include "tee_decrypt.h" +TEE_Result tee_internal_teeupgrade_key(uint8_t *out_buf, uint32_t *out_size); +#ifdef USEONBIOS +const unsigned char PUB_KEY[] = +"-----BEGIN PUBLIC KEY-----\n" +"MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAy7ZPqveyZEk0n/Hqufz+\n" +"IqN3g7CgW9S+4D6YPw6C2ZD33QkieDOj4SAEkMfYgAnJ7ZHDzTbCJukejGNvUjo0\n" +"tD9UtfUx7PtCvrXKYRHsfBkLEwcHM6+cxVN+bF+bgPu70Vohw8++/AYTLSQKEi/d\n" +"iL+/VUkx6eOZORt+mx4RewvceIJeRFf1l4uWHhz52W1ClOCzO9IveZuxitXrOePP\n" +"IvJ1CA0tZYh/49h5vw6XRdqwMtTr5lybPkPmxzcCcRomnnvDF62S9oqh7e/+mU70\n" +"EsRNCQBKKpSnmiTr/NNDkTD16ZNuYZbrKxRXqqITceGPrgmcnqyys5qf6f5AlW+v\n" +"lozwWl63aVFbGjLgOMVEbywo8Yz7jHjW9TmiqT9GhL4G1CR9dLNNmv4LgVn87zf/\n" +"IcBx89v9DzZ8PFGFNQSYVQP3piimA/VcgCsic43HIdP6bJ+FTOIqMyr19GDG7JeB\n" +"c8ErjJnjB0jSL+GLRbbWrQfwtucrW5GbjWG1D+NRk7W8TXtAtOlPUz0ra97nFdQe\n" +"8f/NO5dcKDHwVp1DYUoGGuOQDYOdyZflge9Kvg/d9euKBLkn8ZPgBxQs2AWlNzDn\n" +"SMmB6IXmWyM2g2PRbYZI4IXTWXSU5IbHayOCS3nBe4qUnEVm79ENRi4XWwdDczbW\n" +"6bD0S5UwU4DJekX0xEkIf8kCAwEAAQ==\n" +"-----END PUBLIC KEY-----\n"; +#else +const unsigned char PUB_KEY[] = +"-----BEGIN PUBLIC KEY-----\n" +"MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtqYgJRlTKZu5p0qYO5x0\n" +"A5w+WzWFvS1X7DURuECygKoeeO70uFiSNUxSGtzR2B19fNHBijSvKSIavdFRsLn+\n" +"EkE0/KzWTDX4rYU/Z2lm1Sex+7Y0bHiBD2lzi5Btz8jNwIswYkAVCmInyHEXTXF9\n" +"wZ6UXdrKo0Y6v+3cBrB5OqO3rjthFpftGjAj9hSJu/dY4Ss6J/2cdECly/kUM+Ws\n" +"WHIT9yGl7HuEBPMU0rmc6NWRSbIsPyRf8Z3y3vBWXORXKu3UkCycFnBGdcoInT4p\n" +"4QKgSNfO6AwP2oL5aMsu0l6cCI9sVXSUx+AflXr1/yvu5S9xXbXcu6ouRV4O/w4I\n" +"pAP+vsN/FVUo/FMDmNKk5QVe2uWQaIcAwqvBsnDargYNKh93wZ9AuL7NAfZLnjwB\n" +"Gal0WXiJrlPNLQCPOfwysugNxa0WzITTZkWv0z39aFhWR6cNAiqE2OWOMkmtj+h+\n" +"5fCYoyRbSWkWa5VVmv11V/rUB0FWo5yz+yMMO5/B00clF8QJ9Dqhc6QZnqNjWWj5\n" +"Hy5V2lrwGUz7pzs5VAvh6QZOCjMo7i2XNuFP/QoKVtJvqTJ5Ped0FBFGRFcy6I75\n" +"qhu0rA1k4shKjPgBdr4BP5B3OKEd64hdR+XWM5FxVnl0ZgLz1xrXBHfKvoRLvzQZ\n" +"Fy1UfuRIW5sRLW+1jF2AXx8CAwEAAQ==\n" +"-----END PUBLIC KEY-----\n"; +#endif +static struct encrypto_head *g_head; +static struct secure_img_header* g_imgheader; +static unsigned char g_decryptedtext[DECRYPT_LENGH] = {0}; +static unsigned char g_privatekey[AES_TEXT_LENGH] = {0}; +static int32_t aes_gcm_256_decrypt(const struct aes_gcm_para *para, const uint8_t *in, uint32_t in_len, uint8_t *out) +{ + EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + tloge("get new ctx failed\n"); + return -1; + } + int32_t len, len2; + if (para == NULL || para->key == NULL || para->iv == NULL || in == NULL || out == NULL || para->tag == NULL) + goto clean; + if (EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL) == 0) { + tloge("set cipher type and mode failed\n"); + goto clean; + } + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, para->iv_len, NULL) == 0) { + tloge("Set IV length failed\n"); + goto clean; + } + if (EVP_DecryptInit_ex(ctx, NULL, NULL, para->key, para->iv) == 0) { + tloge("Specify key and IV failed\n"); + goto clean; + } + if (para->aad != NULL && para->aad_len > 0) { + if (EVP_DecryptUpdate(ctx, NULL, &len, para->aad, para->aad_len) <= 0) { + tloge("set aad value failed\n"); + goto clean; + } + } + if (EVP_DecryptUpdate(ctx, out, &len, in, in_len) == 0) { + tloge("decrypt update failed\n"); + goto clean; + } + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, para->tag_len, (void* )(para->tag)) <= 0) { + tloge("set tag value failed\n"); + goto clean; + } + if (EVP_DecryptFinal_ex(ctx, out + len, &len2)<=0) { + tloge("authentication failed and plaintext is not trustworthy.\n"); + goto clean; + } + if (len + len2 < len) { + tloge("len and len2's addition may overflow\n"); + goto clean; + } + EVP_CIPHER_CTX_free(ctx); + return len + len2; +clean: + EVP_CIPHER_CTX_free(ctx); + return -1; +} + +/* Process steps: + * 1, Get public key, + * 2, Verify the signature using the public key, + */ +int32_t openssl_rsa_verify(const uint8_t *hash, uint32_t hash_size, const uint8_t *signature, + uint32_t signature_size) +{ + bool check = (hash == NULL || signature == NULL || signature_size == 0 || hash_size == 0); + if (check) { + tloge("check parameteres failed\n"); + return -1; + } + BIO *mem = BIO_new_mem_buf(PUB_KEY, -1); + if (mem == NULL) { + tloge("get bio mem buf failed\n"); + return -1; + } + RSA *rsa_pub_key = PEM_read_bio_RSA_PUBKEY(mem, NULL, NULL, NULL); + BIO_free(mem); + mem = NULL; + if (rsa_pub_key == NULL) { + tloge("get rsa pub key failed\n"); + return -1; + } + /* the sign len should equals rsa pub key's n size */ + uint32_t modulus_size = (uint32_t)RSA_size(rsa_pub_key); + if (signature_size < modulus_size) { + tloge("Invalid signature size = 0x%x\n", signature_size); + RSA_free(rsa_pub_key); + rsa_pub_key = NULL; + return -1; + } + BIO *bio = BIO_new(BIO_s_mem()); + if (bio == NULL) { + tloge("get bio failed\n"); + RSA_free(rsa_pub_key); + rsa_pub_key = NULL; + return -1; + } + PEM_write_bio_RSA_PUBKEY(bio, rsa_pub_key); + BIO_free(bio); + bio = NULL; + int32_t result = RSA_verify(NID_sha256, hash, hash_size, signature, signature_size, rsa_pub_key); + RSA_free(rsa_pub_key); + rsa_pub_key = NULL; + if (result != 1) { + tloge("signature VerifyDigest fail\n"); + return -1; + } + return 0; +} +static int get_para_info(void) +{ + uint32_t out_size = AES_TEXT_LENGH; + if(tee_internal_teeupgrade_key(g_privatekey, &out_size) != TEE_SUCCESS) { + tloge("get private key failed \n"); + return -1; + } + BIO *mem = BIO_new_mem_buf(g_privatekey, -1); + if (mem == NULL) { + tloge("get bio mem buf failed\n"); + return -1; + } + RSA *tee_load_priv_key = PEM_read_bio_RSAPrivateKey(mem, NULL, NULL, NULL); + BIO_free(mem); + mem = NULL; + if (tee_load_priv_key == NULL) { + tloge("get rsa private key failed\n"); + return -1; + } + /* key size 4096, RSA OAEP mode */ + int32_t out_len = RSA_private_decrypt(DECRYPT_LENGH, (const uint8_t *)(g_head->enc_key), + (uint8_t *)g_decryptedtext, tee_load_priv_key, RSA_PKCS1_OAEP_PADDING); + RSA_free(tee_load_priv_key); + tee_load_priv_key = NULL; + if (out_len < 0) { + tloge("Failed to decrypt cipher layer of TEE image\n"); + return -1; + } + return 0; +} +int load_encrypted_teeos(const uint8_t *img_src_addr, uint32_t* image_len, uint8_t *decrypt_teeos) +{ + if(img_src_addr == NULL || image_len == NULL || decrypt_teeos == NULL) { + tloge("load_encrypted_teeos parameteres Invalid\n"); + return -1; + } + g_head = (struct encrypto_head *)((uintptr_t)(img_src_addr)); + if (g_head->magic != MAGIC) { + tloge("load_encrypted_teeos img_magic error, magic = 0x%x\n", g_head->magic); + return -1; + } + if (*image_len < ENCRYPTO_HEAD_SIZE || g_head->encrypto_img_size > *image_len - ENCRYPTO_HEAD_SIZE) { + tloge("load_encrypted_teeos img_size error, size = 0x%x\n", g_head->encrypto_img_size); + return -1; + } + if (get_para_info() <0 ) { + tloge("get para info failed\n"); + return -1; + } + // use aes key to decrypt tee image + // key: 0-31byte, iv:32-47byte, tag:48-63byte + struct aes_gcm_para para = { + .key = (uint8_t *)g_decryptedtext, + .iv = (uint8_t*)(g_decryptedtext + IV_OFFSET), + .iv_len = IV_LENGH, + .tag = (uint8_t*)(g_decryptedtext + TAG_OFFSET), + .tag_len = TAG_LENGH, + .aad = NULL, + .aad_len = 0, + }; + int ret = aes_gcm_256_decrypt(¶, (const uint8_t *)((uintptr_t)img_src_addr + ENCRYPTO_HEAD_SIZE), + g_head->encrypto_img_size, decrypt_teeos); + if(ret == -1) { + memset_s(g_decryptedtext, sizeof(g_decryptedtext), 0, sizeof(g_decryptedtext)); + tloge("aes_gcm_256_decrypt failed\n"); + return -1; + } + *image_len = (uint32_t)ret; + memset_s(g_decryptedtext, sizeof(g_decryptedtext), 0, sizeof(g_decryptedtext)); + return 0; +} + +int load_verify_teeos(const uint8_t *img_src_addr, uint8_t *tee_addr, uint32_t buf_len, uint32_t *header_size) +{ + if(img_src_addr == NULL || tee_addr == NULL || header_size == NULL) { + tloge("load_verify_teeos parameteres Invalid\n"); + return -1; + } + int ret; + unsigned char hash_result[HASH_LENGH]; + if (buf_len < sizeof(struct secure_img_header)) { + tloge("buf_len smaller than size of g_imgheader\n"); + return -1; + } + g_imgheader = (struct secure_img_header*)((uintptr_t)(tee_addr)); + if (g_imgheader->kernel_offset > buf_len) { + tloge("g_imgheader->kernel_offset=0x%llx is too big\n", g_imgheader->kernel_offset); + return -1; + } + if (buf_len < SIG_LENGH || g_imgheader->sig_offset > buf_len - SIG_LENGH) { + tloge("g_imgheader->sig_offset=0x%llx is too big\n", g_imgheader->sig_offset); + return -1; + } + SHA256((uint8_t *)(uintptr_t)(tee_addr), (size_t)(g_imgheader->sig_offset), hash_result); + ret = openssl_rsa_verify(hash_result, HASH_LENGH, // 32 + ((unsigned char*)(uintptr_t)(tee_addr) + g_imgheader->sig_offset), SIG_LENGH); // 512 + if (ret != 0) { + tloge("openssl_rsa_verify ret fail! ret=-0x%04x\n", -ret); + return -1; + } + *header_size = g_imgheader->header_size; + return 0; +} diff --git a/test/TA/tee_upgrade/src/tee_decrypt.h b/test/TA/tee_upgrade/src/tee_decrypt.h new file mode 100644 index 0000000..16bd31b --- /dev/null +++ b/test/TA/tee_upgrade/src/tee_decrypt.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. + * Licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: tee_upgrade TA : tee_decrypt.h. + */ + +#ifndef TEE_UPGRADE_H +#define TEE_UPGRADE_H +#define IMAGE_MAX_LENGH (0x4000000) +#define TEXT_MAX_LENGH (0x4000000) +#define ENCRYPTO_HEAD_SIZE (0x224) + +#define MAGIC 0x5A5AA5A5 +#define KEY_INFO_MAX 8 + +#define IV_LENGH 16 +#define TAG_LENGH 16 +#define IV_OFFSET 32 +#define TAG_OFFSET 48 + +#define HASH_LENGH 32 +#define SIG_LENGH 512 +#define IMG_REV_LENGH 6 +#define ENC_KEY_LENGH 512 +#define DECRYPT_LENGH 512 +#define AES_TEXT_LENGH 3269 +struct encrypto_head { + uint32_t magic; + uint32_t img_version; + uint32_t img_reserve[IMG_REV_LENGH]; + unsigned char enc_key[ENC_KEY_LENGH]; // key(32) iv(16) tag(16) + uint32_t encrypto_img_size; +}; +struct asym_key_t { + uint32_t key_magic; + uint32_t key_offset; + int32_t key_size; +}; +struct aes_gcm_para { + uint8_t *key; + uint8_t *iv; + int iv_len; + uint8_t *tag; + int tag_len; + uint8_t *aad; + int aad_len; +}; +struct secure_img_header { + uint32_t header_size; + unsigned long long kernel_load_addr; + uint32_t kernel_size; + uint32_t secure_img_version; + uint32_t task_total_size; + uint32_t got_size; + unsigned long long image_load_addr; + unsigned long long task_offset; + unsigned long long kernel_offset; // kernel entry offset + uint32_t sig_key_version; + unsigned long long sig_offset; // signature offset + struct asym_key_t teeos_key_info[KEY_INFO_MAX]; +}__attribute__((packed)); +int load_encrypted_teeos(const uint8_t *img_src_addr, uint32_t* image_len, uint8_t *decrypt_teeos); +int load_verify_teeos(const uint8_t *img_src_addr, uint8_t *tee_addr, uint32_t buf_len, uint32_t *header_size); +#endif diff --git a/test/TA/tee_upgrade/src/upgrade.c b/test/TA/tee_upgrade/src/upgrade.c new file mode 100644 index 0000000..e7ee555 --- /dev/null +++ b/test/TA/tee_upgrade/src/upgrade.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. + * Licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: tee upgrade TA : upgrade.c. + */ + +#include +#include +#include +#include "tee_decrypt.h" +#define PAGE_SIZE 0x1000 +#define ALIGN_UP(x, align) (((x) + ((align)-1)) & ~((align)-1)) +#define CACHE_LINE 64 + +#define MAX_IMAGE_LENGTH 0x1000000 +#define UPGRADE_SEND_IMAGE_BEGIN 0xaa +#define UPGRADE_SEND_IMAGE_UPDATE 0xbb +#define UPGRADE_SEND_IMAGE_FINISH 0xcc + +static uint8_t *g_encrypt_img_buf = NULL; +static uint8_t *g_decrypt_img_buf = NULL; +static uint32_t g_buffer_offset = 0; +static uint32_t g_total_len = 0; + +int32_t set_image_addr(uint64_t vaddr, uint64_t size); +TEE_Result tee_internal_teeupgrade_key(uint8_t *out_buf, uint32_t *out_size); +void dma_inv_range(uint64_t start, uint64_t end); +void dma_clean_range(uint64_t start, uint64_t end); + +TEE_Result TA_CreateEntryPoint(void) +{ + TEE_Result ret; + ret = addcaller_ca_exec("tee_upgrade", "root"); + if (ret != TEE_SUCCESS) { + tloge("add caller failed\n"); + return ret; + } + return TEE_SUCCESS; +} + +TEE_Result TA_OpenSessionEntryPoint(uint32_t paramTypes, TEE_Param params[4], void **sessionContext) +{ + (void)paramTypes; + (void)params; + (void)sessionContext; + return TEE_SUCCESS; +} + +static TEE_Result create_image_buffer(uint32_t paramTypes, TEE_Param *params) +{ + if (!check_param_type(paramTypes, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_VALUE_INPUT)) { + tloge("Bad expected parameter types, 0x%x.\n", paramTypes); + return TEE_ERROR_BAD_PARAMETERS; + } + + uint32_t image_len = ALIGN_UP(params[3].value.a, PAGE_SIZE); + tlogi("the image len is %x\n", image_len); + + if (image_len == 0 || image_len > MAX_IMAGE_LENGTH) { + tloge("invalid image length\n"); + return TEE_ERROR_BAD_PARAMETERS; + } + + if (g_total_len == 0) + g_total_len = image_len; + + if (g_encrypt_img_buf == NULL) { + g_encrypt_img_buf = TEE_Malloc(g_total_len, 0); + if (g_encrypt_img_buf == NULL) { + tloge("malloc encrypt image buffer failed\n"); + return TEE_ERROR_OUT_OF_MEMORY; + } + } + + if (g_decrypt_img_buf == NULL) { + g_decrypt_img_buf = malloc_coherent(g_total_len); + if (g_decrypt_img_buf == NULL) { + tloge("malloc decrypt image buffer failed\n"); + TEE_Free(g_encrypt_img_buf); + g_encrypt_img_buf = NULL; + return TEE_ERROR_OUT_OF_MEMORY; + } + } + return TEE_SUCCESS; +} + +static TEE_Result handle_image_buffer(uint32_t paramTypes, TEE_Param *params) +{ + if (g_encrypt_img_buf == NULL || g_decrypt_img_buf == NULL) { + tloge("invalid image buffer\n"); + return TEE_ERROR_OUT_OF_MEMORY; + } + + if (!check_param_type(paramTypes, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_MEMREF_INPUT, + TEE_PARAM_TYPE_NONE)) { + tloge("Bad expected parameter types, 0x%x.\n", paramTypes); + return TEE_ERROR_BAD_PARAMETERS; + } + + uint8_t *buf = params[2].memref.buffer; + if (buf == NULL) { + tloge("invalid buf!\n"); + return TEE_ERROR_GENERIC; + } + uint32_t size = params[2].memref.size; + + if (g_total_len < g_buffer_offset) { + tloge("invalid offset %u\n",g_buffer_offset); + return TEE_ERROR_GENERIC; + } + + int rc = memcpy_s(g_encrypt_img_buf + g_buffer_offset, g_total_len - g_buffer_offset, buf, size); + if (rc != 0) { + tloge("memcpy failed\n"); + return TEE_ERROR_GENERIC; + } + g_buffer_offset += size; + + return TEE_SUCCESS; +} + +static void flush_teeos(uintptr_t addr, uint32_t size) +{ + uint32_t index = 0; + for (index = 0; index < (size / CACHE_LINE); index++) + dma_clean_range(addr + CACHE_LINE * index, addr + CACHE_LINE * index + CACHE_LINE); + + for (index = 0; index < (size / CACHE_LINE); index++) + dma_inv_range(addr + CACHE_LINE * index, addr + CACHE_LINE * index + CACHE_LINE); +} + +static TEE_Result send_image_buffer(uint32_t paramTypes) +{ + if (g_encrypt_img_buf == NULL || g_decrypt_img_buf == NULL) { + tloge("invalid image buffer\n"); + return TEE_ERROR_OUT_OF_MEMORY; + } + + if (!check_param_type(paramTypes, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE)) { + tloge("Bad expected parameter types, 0x%x.\n", paramTypes); + return TEE_ERROR_BAD_PARAMETERS; + } + // decrypt here + int rc; + uint32_t len = g_total_len; + uint32_t header_size = 0; + rc = load_encrypted_teeos(g_encrypt_img_buf, &len, g_decrypt_img_buf); + if (rc != 0) { + tloge("load_encrypted_teeos failed\n"); + return -1; + } + + rc = load_verify_teeos(g_encrypt_img_buf, g_decrypt_img_buf, g_total_len, &header_size); + if (rc != 0) { + tloge("load_verify_teeos failed\n"); + return TEE_ERROR_GENERIC; + } + + if (len <= header_size) { + tloge("header_size larger than len\n"); + return TEE_ERROR_GENERIC; + } + len -= header_size; + if (g_total_len < header_size || len > g_total_len - header_size) { + tloge("len is too large\n"); + return TEE_ERROR_GENERIC; + } + rc = memmove_s((void *)g_decrypt_img_buf, g_total_len, (void *)(g_decrypt_img_buf + header_size), len); + if (rc != 0 ) { + tloge("memmove_s failed\n"); + return TEE_ERROR_GENERIC; + } + + flush_teeos((uintptr_t)g_decrypt_img_buf, g_total_len); + rc = set_image_addr((uint64_t)(uintptr_t)g_decrypt_img_buf, len); + if (rc != 0) { + tloge("set image addr failed\n"); + return TEE_ERROR_GENERIC; + } + return TEE_SUCCESS; +} + +TEE_Result TA_InvokeCommandEntryPoint(void *session_context, uint32_t cmd_id, uint32_t paramTypes, TEE_Param params[4]) +{ + (void)session_context; + switch (cmd_id) { + case UPGRADE_SEND_IMAGE_BEGIN: + return create_image_buffer(paramTypes, params); + case UPGRADE_SEND_IMAGE_UPDATE: + return handle_image_buffer(paramTypes, params); + case UPGRADE_SEND_IMAGE_FINISH: + return send_image_buffer(paramTypes); + default: + tloge("invalid cmd\n"); + return TEE_ERROR_BAD_PARAMETERS; + } + return TEE_SUCCESS; +} + +void TA_CloseSessionEntryPoint(void *session_context) +{ + (void)session_context; + if (g_encrypt_img_buf != NULL) { + free(g_encrypt_img_buf); + g_encrypt_img_buf = NULL; + } + if (g_decrypt_img_buf != NULL) { + free(g_decrypt_img_buf); + g_decrypt_img_buf = NULL; + } +} + +void TA_DestroyEntryPoint(void) +{ + tlogd("upgrade ta exit\n"); +} -- Gitee From c5ca363f98643d9ef0696d57c64915bfdcb406b5 Mon Sep 17 00:00:00 2001 From: LVZE Date: Thu, 29 Jun 2023 08:22:54 +0000 Subject: [PATCH 2/2] update test/CA/tee_upgrade/upgrade.c. Signed-off-by: LVZE --- test/CA/tee_upgrade/upgrade.c | 387 +++++++++++++++++----------------- 1 file changed, 191 insertions(+), 196 deletions(-) diff --git a/test/CA/tee_upgrade/upgrade.c b/test/CA/tee_upgrade/upgrade.c index e583285..863e299 100644 --- a/test/CA/tee_upgrade/upgrade.c +++ b/test/CA/tee_upgrade/upgrade.c @@ -14,13 +14,13 @@ #include #include #include -#include "tee_client_api.h" +#include "teek_client_api.h" #include -#define PART_IMAGE_LEN 0x100000 -#define UPGRADE_SEND_IMAGE_BEGIN 0xaa -#define UPGRADE_SEND_IMAGE_UPDATE 0xbb -#define UPGRADE_SEND_IMAGE_FINISH 0xcc +#define PART_IAMGE_LEN 0x100000 +#define UPGRADE_SEND_IMAGE_BEGIN 0xaa +#define UPGRADE_SEND_IMAGE_UPDATE 0xbb +#define UPGRADE_SEND_IMAGE_FINISH 0xcc #define MAX_IMAGE_LENGTH 0x1000000 #ifndef CONFIG_TEE_IMG_PATH #define CONFIG_TEE_IMG_PATH "/var/itrustee/image/trustedcore.img" @@ -34,251 +34,246 @@ extern int tee_reboot(void); static int32_t teek_open_app_file(struct file *fp, char **file_buf, uint32_t total_img_len) { - loff_t pos = 0; - uint32_t read_size; - char *file_buffer = NULL; - - if (total_img_len == 0 || total_img_len > MAX_IMAGE_LENGTH) { - tloge("img len is invalied, len=%u\n", total_img_len); - return TEEC_ERROR_BAD_PARAMETERS; - } - - file_buffer = vmalloc(total_img_len); - if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)file_buffer)) { - tloge("alloc TA file buffer(size=%u) failed\n", total_img_len); - return TEEC_ERROR_GENERIC; - } - - read_size = (uint32_t)kernel_read(fp, file_buffer, total_img_len, &pos); - if (read_size != total_img_len) { - tloge("read ta file failed, read size/total size=%u/%u\n", read_size, total_img_len); - vfree(file_buffer); - return TEEC_ERROR_GENERIC; - } - - *file_buf = file_buffer; - - return TEEC_SUCCESS; + loff_t pos = 0; + uint32_t read_size; + char *file_buffer = NULL; + + if (total_img_len == 0 || total_img_len > MAX_IMAGE_LENGTH) { + tloge("img len is invalied, len=%u\n", total_img_len); + return TEEC_ERROR_BAD_PARAMETERS; + } + + file_buffer = vmalloc(total_img_len); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)file_buffer)) { + tloge("alloc TA file buffer(size=%u) failed\n", total_img_len); + return TEEC_ERROR_GENERIC; + } + + read_size = (uint32_t)kernel_read(fp, file_buffer, total_img_len, &pos); + if (read_size != total_img_len) { + tloge("read ta file failed, read size/total size=%u/%u\n", read_size, total_img_len); + vfree(file_buffer); + return TEEC_ERROR_GENERIC; + } + + *file_buf = file_buffer; + + return TEEC_SUCCESS; } static int32_t teek_read_app(const char *load_file, char **file_buf, uint32_t *file_len) { - int32_t ret; - struct file *fp = NULL; - - fp = file_open(load_file, O_RDONLY, 0); - if (!fp || IS_ERR(fp)) { - tloge("open file error, err = %ld\n", PTR_ERR(fp)); - return TEEC_ERROR_BAD_PARAMETERS; - } - - if (!fp->f_inode) { - tloge("node is NULL\n"); - filp_close(fp, 0); - return TEEC_ERROR_BAD_PARAMETERS; - } - - *file_len = (uint32_t)(fp->f_inode->i_size); - - ret = teek_open_app_file(fp, file_buf, *file_len); - if (ret != TEEC_SUCCESS) - tloge("do read app fail\n"); - - if (fp != NULL) { - filp_close(fp, 0); - fp = NULL; - } - - return ret; + int32_t ret; + struct file *fp = NULL; + + fp = filp_open(load_file, O_RDONLY, 0); + if (!fp || IS_ERR(fp)) { + tloge("open file error, err=%ld\n", PTR_ERR(fp)); + return TEEC_ERROR_BAD_PARAMETERS; + } + + if (!fp->f_inode) { + tloge("node is NULL\n"); + filp_close(fp, 0); + return TEEC_ERROR_BAD_PARAMETERS; + } + + *file_len = (uint32_t)(fp->f_inode->i_size); + + ret = teek_open_app_file(fp, file_buf, *file_len); + if (ret != TEEC_SUCCESS) + tloge("do read app fail\n"); + + if (fp != NULL) { + filp_close(fp, 0); + fp = NULL; + } + + return ret; } -statc void teek_free_app(bool load_app_flag, char **file_buf) +static void teek_free_app(bool load_app_flag, char **file_buf) { - if (load_app_flag && file_buf != NULL && ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)(*file_buf))) { - vfree(*file_buf); - *file_buf = NULL; - } + if (load_app_flag && file_buf != NULL && ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)(*file_buf))) { + vfree(*file_buf); + *file_buf = NULL; + } } -static int32_t teek_get_app(const char *ta_path, char ** file_buf, uint32_t *file_len) +static int32_t teek_get_app(const char *ta_path, char **file_buf, uint32_t *file_len) { - int32_t ret; + int32_t ret; - if (!ta_path) - return TEEC_ERROR_BAD_PARAMETERS; + if (!ta_path) + return TEEC_ERROR_BAD_PARAMETERS; - if (!file_buf || !file_len) { - tloge("load app params invalid\n"); - return TEEC_ERROR_BAD_PARAMETERS; - } + if (!file_buf || !file_len) { + tloge("load app params invalied\n"); + return TEEC_ERROR_BAD_PARAMETERS; + } - ret = teek_read_app(ta_path, file_buf, file_len); - if (ret != TEEC_SUCCESS) - tloge("teec load app error, err=%d\n", ret); + ret = teek_read_app(ta_path, file_buf, file_len); + if (ret != TEEC_SUCCESS) + tloge("teec load app error, err=%d\n", ret); - return ret; + return ret; } -static int send_image_begin(TEEC_Session *TEEC_Session, uint32_t image_length) +static int send_image_begin(TEEC_Session *tee_session, uint32_t image_length) { - uint32_t origin = 0; - TEEC_OpenSession operation = {0}; - int ret = 0; - - operation.started = 1; - operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_VALUE_INPUT); - operation.params[ARRAY_INDEX3].value.a = image_length; - - ret = TEEK_InvokeCommand(TEEC_Session, UPGRADE_SEND_IMAGE_BEGIN, &operation, &origin); - if (ret != 0) { - tloge("TEEK_InvokeCommand failed\n"); - return -1; - } - return 0; + uint32_t origin = 0; + TEEC_Operation operation = {0}; + int ret = 0; + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_VALUE_INPUT); + operation.params[ARRAY_INDEX3].value.a = image_length; + + ret = TEEK_InvokeCommand(tee_session, UPGRADE_SEND_IMAGE_BEGIN, &operation, &origin); + if (ret != 0) { + tloge("TEEK_InvokeCommand failed\n"); + return -1; + } + return 0; } static int send_image_update(TEEC_Session *tee_session, char *file_buf, uint32_t image_length) { - uint32_t origin = 0; - uint32_t idx = 0; - uint32_t left_len = image_length; - int ret = 0; + uint32_t origin = 0; + uint32_t idx = 0; + uint32_t left_len = image_length; + int ret = 0; - TEEC_OpenSession operation = {0}; + TEEC_Operation operation = {0}; operation.started = 1; operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE); - while (left_len > 0) { - uint32_t len = (left_len >= PART_IMAGE_LEN) ? PART_IMAGE_LEN : left_len; - operation.params[ARRAY_INDEX2].tmpref.buffer = file_buf + idx * PART_IMAGE_LEN; - operation.params[ARRAY_INDEX2].tmpref.size = len; - ret = TEEK_InvokeCommand(tee_session, UPGRADE_SEND_IMAGE_UPDATE, &operation, &origin); - if (ret != 0) { - tloge("send image update failed\n"); - return -1; - } - left_len -= len; - idx++; - } - return 0; + while (left_len > 0) { + uint32_t len = (left_len >= PART_IAMGE_LEN) ? PART_IAMGE_LEN : left_len; + operation.params[ARRAY_INDEX2].tmpref.buffer = file_buf + idx * PART_IAMGE_LEN; + operation.params[ARRAY_INDEX2].tmpref.size = len; + ret = TEEK_InvokeCommand(tee_session, UPGRADE_SEND_IMAGE_UPDATE, &operation, &origin); + if (ret != 0) { + tloge("send image update failed\n"); + return -1; + } + left_len -= len; + idx++; + } + return 0; } static int send_image_finish(TEEC_Session *tee_session) { - uint32_t origin = 0; - int ret = 0; - TEEC_Operation operation = {0}; - operation.started = 1; - operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); - - ret = TEEK_InvokeCommand(tee_session, UPGRADE_SEND_IMAGE_FINISH, &operation, &origin); - if (ret != 0) { - tloge("send image finish failed\n"); - return -1; - } - - return ret; + uint32_t origin = 0; + int ret = 0; + TEEC_Operation operation = {0}; + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + + ret = TEEK_InvokeCommand(tee_session, UPGRADE_SEND_IMAGE_FINISH, &operation, &origin); + if (ret != 0) { + tloge("send image finish failed\n"); + return -1; + } + + return ret; } static int get_new_tee_image(TEEC_Session *tee_session) { - char *file_buf = NULL; - uint32_t image_length = 0; - - int ret = teek_get_app(CONFIG_TEE_IMG_PATH, &file_buf, &image_length); - if (ret != 0) { - tloge("get new tee image failed, use origin tee\n"); - teek_free_app(true, &file_buf); - return -1; - } + char *file_buf = NULL; + uint32_t image_length = 0; - ret = send_image_begin(tee_session, image_length); - if (ret != 0) { - tloge("send image begin failed\n"); + int ret = teek_get_app(CONFIG_TEE_IMG_PATH, &file_buf, &image_length); + if (ret != 0) { + tloge("get new tee image failed, use origin tee\n"); teek_free_app(true, &file_buf); - return -1; - } + return -1; + } - ret = send_image_begin(tee_session, image_length); - if (ret != 0) { - tloge("send image begin failed\n"); + ret = send_image_begin(tee_session, image_length); + if (ret != 0) { + tloge("send image begin failed\n"); teek_free_app(true, &file_buf); - return -1; - } + return -1; + } - ret = send_image_update(tee_session, file_buf, image_length); - if (ret != 0) { - tloge("send image update failed\n"); + ret = send_image_update(tee_session, file_buf, image_length); + if (ret != 0) { + tloge("send image update failed\n"); teek_free_app(true, &file_buf); - return -1; - } + return -1; + } - ret = send_image_finish(tee_session); - if (ret != 0) { - tloge("send image end failed\n"); + ret = send_image_finish(tee_session); + if (ret != 0) { + tloge("send image end failed\n"); teek_free_app(true, &file_buf); - return -1; - } + return -1; + } - teek_free_app(true, &file_buf); - return 0; + teek_free_app(true, &file_buf); + return 0; } + // 9ab6f960-54f3-4317-a8f7-e92ed12b6ae2.sec static const TEEC_UUID g_tee_uuid = { - 0x9ab6f960U, 0x54f3, 0x4317, - { 0xa8, 0xf7, 0xe9, 0x2e, 0xd1, 0x2b, 0x6a, 0xe2 } + 0x9ab6f960U, 0x54f3, 0x4317, + { 0xa8, 0xf7, 0xe9, 0x2e, 0xd1, 0x2b, 0x6a, 0xe2 } }; static int32_t __init upgrade_init(void) { - TEEC_Result ret; - TEEC_Context ctx; - TEEC_Operation operation = {0}; - TEEC_Session tee_session; - uint32_t origin = 0; - uint32_t root_id = 0; - - ret = TEEK_InitializeContext(NULL, &ctx); - if (ret != 0) { - tloge("initialize context failed\n"); - return -1; - } - - operation.started = 1; - operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT); - operation.params[ARRAY_INDEX2].tmpref.buffer = (void *)(&root_id); - operation.params[ARRAY_INDEX2].tmpref.size = sizeof(root_id); - operation.params[ARRAY_INDEX3].tmpref.buffer = (void *)("tee_upgrade"); - operation.params[ARRAY_INDEX3].tmpref.size = strlen("tee_upgrade") + 1; - - ctx.ta_path = (uint8_t *)("/var/itrustee/image/9ab6f960-54f3-4317-a8f7-e92ed12b6ae2.sec"); - ret = TEEK_OpenSession(&ctx, &tee_session, &g_tee_uuid, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); - if (ret != 0) { - tloge("TEEK_OpenSession failed\n"); - TEEK_FinalizeContext(&ctx); - return -1; - } - - ret = get_new_tee_image(&tee_session); - if (ret != 0) { - TEEK_CloseSession(&tee_session); - TEEK_FinalizeContext(&ctx); - return -1; - } - - TEEK_CloseSession(&tee_session); - TEEK_FinalizeContext(&ctx); - ret = (TEEC_Result)tee_reboot(); - if (ret != TEEC_SUCCESS) - return -1; - tlogi("teeos upgrade done"); - return 0; + TEEC_Result ret; + TEEC_Context ctx; + TEEC_Operation operation = {0}; + TEEC_Session tee_session; + uint32_t origin = 0; + uint32_t root_id = 0; + + ret = TEEK_InitializeContext(NULL, &ctx); + if (ret != 0) { + tloge("initialize context failed\n"); + return -1; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT); + operation.params[ARRAY_INDEX2].tmpref.buffer = (void *)(&root_id); + operation.params[ARRAY_INDEX2].tmpref.size = sizeof(root_id); + operation.params[ARRAY_INDEX3].tmpref.buffer = (void *)("tee_upgrade"); + operation.params[ARRAY_INDEX3].tmpref.size = strlen("tee_upgrade") + 1; + + ctx.ta_path = (uint8_t *)("/var/itrustee/image/9ab6f960-54f3-4317-a8f7-e92ed12b6ae2.sec"); + ret = TEEK_OpenSession(&ctx, &tee_session, &g_tee_uuid, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret != 0) { + tloge("TEEK_OpenSession failed\n"); + TEEK_FinalizeContext(&ctx); + return -1; + } + + ret = get_new_tee_image(&tee_session); + if (ret != 0) { + TEEK_CloseSession(&tee_session); + TEEK_FinalizeContext(&ctx); + return -1; + } + + TEEK_CloseSession(&tee_session); + TEEK_FinalizeContext(&ctx); + ret = (TEEC_Result)tee_reboot(); + if (ret != TEEC_SUCCESS) + return -1; + tlogi("teeos upgrade done\n"); + return 0; } + static void __exit upgrade_exit(void) { - tlogi("remove upgrade ca\n"); + tlogi("remove upgrade ca\n"); } module_init(upgrade_init); -- Gitee