diff --git a/0018-some-adaptations-for-trustzone.patch b/0018-some-adaptations-for-trustzone.patch new file mode 100644 index 0000000000000000000000000000000000000000..70d6e5f758604aa5d189baf9845a390653d478ee --- /dev/null +++ b/0018-some-adaptations-for-trustzone.patch @@ -0,0 +1,2079 @@ +From 174b6d30d4b8d80a8539015fe37b7b4d13fa8c30 Mon Sep 17 00:00:00 2001 +From: zhangguangzhi +Date: Mon, 17 May 2021 22:35:43 +0800 +Subject: [PATCH] some adaptations for trustzone + +Signed-off-by: zhangguangzhi +--- + CMakeLists.txt | 11 +- + examples/CMakeLists.txt | 28 ++ + examples/helloworld/CMakeLists.txt | 3 +- + examples/helloworld/enclave/CMakeLists.txt | 16 +- + examples/helloworld/enclave/config_cloud.ini | 49 ++ + examples/helloworld/enclave/manifest.txt | 7 + + examples/helloworld/enclave/manifest.txt.in | 8 - + examples/helloworld/host/CMakeLists.txt | 7 +- + examples/helloworld/host/main.c | 1 + + examples/seal_data/CMakeLists.txt | 4 +- + examples/seal_data/enclave/CMakeLists.txt | 19 +- + examples/seal_data/enclave/config_cloud.ini | 49 ++ + examples/seal_data/enclave/manifest.txt | 7 + + examples/seal_data/enclave/manifest.txt.in | 8 - + examples/seal_data/host/CMakeLists.txt | 1 + + .../gp/itrustee/itrustee_seal_data.c | 3 +- + src/host_src/gp/CMakeLists.txt | 4 +- + src/host_src/gp/gp_enclave.c | 4 +- + .../{ => cloud}/rsa_public_key_cloud.pem | 0 + tools/sign_tool/generate_signature.py | 56 +++ + tools/sign_tool/manifest.py | 170 ++++--- + tools/sign_tool/sign_tool.py | 471 ------------------ + tools/sign_tool/sign_tool.sh | 141 ++---- + tools/sign_tool/signtool_v3.py | 428 ++++++++++++++++ + 24 files changed, 791 insertions(+), 704 deletions(-) + create mode 100644 examples/CMakeLists.txt + create mode 100644 examples/helloworld/enclave/config_cloud.ini + create mode 100644 examples/helloworld/enclave/manifest.txt + delete mode 100644 examples/helloworld/enclave/manifest.txt.in + create mode 100644 examples/seal_data/enclave/config_cloud.ini + create mode 100644 examples/seal_data/enclave/manifest.txt + delete mode 100644 examples/seal_data/enclave/manifest.txt.in + rename tools/sign_tool/{ => cloud}/rsa_public_key_cloud.pem (100%) + create mode 100644 tools/sign_tool/generate_signature.py + delete mode 100644 tools/sign_tool/sign_tool.py + create mode 100644 tools/sign_tool/signtool_v3.py + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 1d036ea..b373328 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -49,17 +49,8 @@ add_subdirectory(src) + + execute_process(COMMAND mkdir ${LOCAL_ROOT_PATH}/bin) + +-if(CC_GP) +- add_subdirectory(${LOCAL_ROOT_PATH}/examples/seal_data) +- add_subdirectory(${LOCAL_ROOT_PATH}/examples/helloworld) +-endif() ++add_subdirectory(examples) + +-if(CC_SGX) +- add_subdirectory(${LOCAL_ROOT_PATH}/examples/helloworld) +- add_subdirectory(${LOCAL_ROOT_PATH}/examples/seal_data) +-# add_subdirectory(${LOCAL_ROOT_PATH}/examples/tls_enclave) +-# add_subdirectory(${LOCAL_ROOT_PATH}/examples/lrt) +-endif() + + install(FILES ${LOCAL_ROOT_PATH}/conf/logrotate.d/secgear + DESTINATION /etc/logrotate.d/) +diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt +new file mode 100644 +index 0000000..382027f +--- /dev/null ++++ b/examples/CMakeLists.txt +@@ -0,0 +1,28 @@ ++add_custom_target(copy ALL ++ COMMAND mkdir -p ${CMAKE_BINARY_DIR}/inc/secGear ++ COMMAND cp ${LOCAL_ROOT_PATH}/inc/host_inc/*.h ${CMAKE_BINARY_DIR}/inc/secGear/ ++ COMMAND cp ${LOCAL_ROOT_PATH}/inc/enclave_inc/*.h ${CMAKE_BINARY_DIR}/inc/secGear/) ++ ++if(CC_GP) ++ add_custom_command(TARGET copy ++ POST_BUILD ++ COMMAND cp ${LOCAL_ROOT_PATH}/inc/host_inc/gp/*.edl ${CMAKE_BINARY_DIR}/inc/secGear/ ++ COMMAND cp ${LOCAL_ROOT_PATH}/inc/host_inc/gp/*.h ${CMAKE_BINARY_DIR}/inc/secGear/ ++ COMMAND cp ${LOCAL_ROOT_PATH}/inc/enclave_inc/gp/*.h ${CMAKE_BINARY_DIR}/inc/secGear/ ++ COMMAND cp ${LOCAL_ROOT_PATH}/inc/enclave_inc/gp/itrustee/*.h ${CMAKE_BINARY_DIR}/inc/secGear/) ++ add_subdirectory(seal_data) ++ add_subdirectory(helloworld) ++endif() ++ ++if(CC_SGX) ++ add_custom_command(TARGET copy ++ POST_BUILD ++ COMMAND shell cp ${LOCAL_ROOT_PATH}/inc/host_inc/sgx/*.h ${CMAKE_BINARY_DIR}/inc/secGear/ ++ COMMAND shell cp ${LOCAL_ROOT_PATH}/inc/host_inc/sgx/*.edl ${CMAKE_BINARY_DIR}/inc/secGear/ ++ COMMAND shell cp ${LOCAL_ROOT_PATH}/inc/enclave_inc/sgx/*.h ${CMAKE_BINARY_DIR}/inc/secGear/) ++ add_subdirectory(seal_data) ++ add_subdirectory(helloworld) ++ #add_subdirectory(tls_enclave) ++ #add_subdirectory(lrt) ++endif() ++ +diff --git a/examples/helloworld/CMakeLists.txt b/examples/helloworld/CMakeLists.txt +index 5da2a6b..843a573 100644 +--- a/examples/helloworld/CMakeLists.txt ++++ b/examples/helloworld/CMakeLists.txt +@@ -20,8 +20,7 @@ set(CODEGEN codegen) + + if(CC_GP) + set(CODETYPE trustzone) +- execute_process(COMMAND uuidgen -r OUTPUT_VARIABLE UUID) +- string(REPLACE "\n" "" UUID ${UUID}) ++ set(UUID f68fd704-6eb1-4d14-b218-722850eb3ef0) + add_definitions(-DPATH="/data/${UUID}.sec") + endif() + +diff --git a/examples/helloworld/enclave/CMakeLists.txt b/examples/helloworld/enclave/CMakeLists.txt +index 0aefdae..f7967ef 100644 +--- a/examples/helloworld/enclave/CMakeLists.txt ++++ b/examples/helloworld/enclave/CMakeLists.txt +@@ -55,7 +55,6 @@ set(COMMON_C_FLAGS "-W -Wall -Werror -fno-short-enums -fno-omit-frame-pointer + set(COMMON_C_LINK_FLAGS "-Wl,-z,now -Wl,-z,relro -Wl,-z,noexecstack -Wl,-nostdlib -nodefaultlibs -nostartfiles") + + if(CC_GP) +- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt.in" "${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt") + + set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} -march=armv8-a ") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s -fPIC") +@@ -72,6 +71,7 @@ if(CC_GP) + + target_include_directories( ${PREFIX} PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} ++ ${LOCAL_ROOT_PATH}/debug/inc + ${LOCAL_ROOT_PATH}/inc/host_inc + ${LOCAL_ROOT_PATH}/inc/host_inc/gp + ${LOCAL_ROOT_PATH}/inc/enclave_inc +@@ -97,14 +97,14 @@ if(CC_GP) + + target_link_libraries(${PREFIX} -lsecgear_tee) + +- add_custom_command(TARGET ${PREFIX} +- POST_BUILD +- COMMAND bash ${SIGN_TOOL} -d sign -x trustzone -i ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${PREFIX}.so -c ${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt +- -o ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT}) ++ #for trustzone compiling, you should connact us to get config and private_key.pem for test, so we will not sign and install binary in this example # ++ # add_custom_command(TARGET ${PREFIX} ++ # POST_BUILD ++ # COMMAND bash ${SIGN_TOOL} -d sign -x trustzone -i ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${PREFIX}.so -c ${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt -m ${CMAKE_CURRENT_SOURCE_DIR}/config_cloud.ini -o ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT}) + +- install(FILES ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT} +- DESTINATION /data +- PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) ++ # install(FILES ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT} ++ # DESTINATION /data ++ # PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + + endif() + +diff --git a/examples/helloworld/enclave/config_cloud.ini b/examples/helloworld/enclave/config_cloud.ini +new file mode 100644 +index 0000000..552f59c +--- /dev/null ++++ b/examples/helloworld/enclave/config_cloud.ini +@@ -0,0 +1,49 @@ ++[config] ++;0 means debug ++;1 means release ++;[fixed value] ++releaseType = 1 ++;;; ++;0 means TA not installed by OTRP ++;1 means TA installed by OTRP ++otrpFlag = 0 ++;;; ++;server address for signing TA ++serverIp= ++;;; ++;public key for encrypt TA ++;[fixed value] ++encryptKey = cloud/rsa_public_key_cloud.pem ++;;; ++;public key length ++;[fixed value] ++encryptKeyLen = 3072 ++;;; ++;0 means not sign ++;1 means signed by local private ++;2 means signed using native sign tool; ++;3 means signed by CI ++;[fixed value] ++signType = 1 ++;;; ++;private key for signing TA ++;[private key owned by yourself] ++signKey = ../../examples/helloworld/enclave/cert/private_key.pem ++;;; ++;private key length for signing TA ++;[key length should be 4096 for security enhance] ++signKeyLen = 4096 ++;;; ++;0 means SHA256 hash type ++;1 means SHA512 hash type ++;[set value to 0 by default] ++hashType = 0 ++;;; ++;0 means padding type is pkcs1v15 ++;1 means padding type is PSS ++;[set value to 0 by default] ++paddingType = 0 ++;;; ++;config file ++;[signed config file by Huawei] ++configPath= ../../examples/helloworld/enclave/signed_config/config +diff --git a/examples/helloworld/enclave/manifest.txt b/examples/helloworld/enclave/manifest.txt +new file mode 100644 +index 0000000..4ef6228 +--- /dev/null ++++ b/examples/helloworld/enclave/manifest.txt +@@ -0,0 +1,7 @@ ++gpd.ta.appID: f68fd704-6eb1-4d14-b218-722850eb3ef0 ++gpd.ta.service_name: rsa-demo ++gpd.ta.singleInstance: true ++gpd.ta.multiSession: false ++gpd.ta.instanceKeepAlive: false ++gpd.ta.dataSize: 819200 ++gpd.ta.stackSize: 40960 +diff --git a/examples/helloworld/enclave/manifest.txt.in b/examples/helloworld/enclave/manifest.txt.in +deleted file mode 100644 +index 7b8ecf5..0000000 +--- a/examples/helloworld/enclave/manifest.txt.in ++++ /dev/null +@@ -1,8 +0,0 @@ +-gpd.ta.appID: @UUID@ +-gpd.ta.service_name: test0108 +-gpd.ta.singleInstance: true +-gpd.ta.multiSession: false +-gpd.ta.multiCommand: false +-gpd.ta.instanceKeepAlive: false +-gpd.ta.dataSize: 16384 +-gpd.ta.stackSize: 20480 +diff --git a/examples/helloworld/host/CMakeLists.txt b/examples/helloworld/host/CMakeLists.txt +index 1c96ffd..60173a9 100644 +--- a/examples/helloworld/host/CMakeLists.txt ++++ b/examples/helloworld/host/CMakeLists.txt +@@ -38,9 +38,10 @@ if(CC_GP) + link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + endif() + add_executable(${OUTPUT} ${SOURCE_FILE} ${AUTO_FILES}) +- target_include_directories(${OUTPUT} PRIVATE +- ${LOCAL_ROOT_PATH}/inc/host_inc +- ${LOCAL_ROOT_PATH}/inc/host_inc/gp ++ target_include_directories(${OUTPUT} PRIVATE ++ ${LOCAL_ROOT_PATH}/debug/inc ++ ${LOCAL_ROOT_PATH}/inc/host_inc ++ ${LOCAL_ROOT_PATH}/inc/host_inc/gp + ${CMAKE_CURRENT_BINARY_DIR}) + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0") + target_link_directories(${OUTPUT} PRIVATE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) +diff --git a/examples/helloworld/host/main.c b/examples/helloworld/host/main.c +index 51993ce..7213a5e 100644 +--- a/examples/helloworld/host/main.c ++++ b/examples/helloworld/host/main.c +@@ -15,6 +15,7 @@ + #include + #include "enclave.h" + #include "helloworld_u.h" ++#include "string.h" + + #define BUF_LEN 32 + +diff --git a/examples/seal_data/CMakeLists.txt b/examples/seal_data/CMakeLists.txt +index 3577301..dce8b81 100644 +--- a/examples/seal_data/CMakeLists.txt ++++ b/examples/seal_data/CMakeLists.txt +@@ -21,9 +21,7 @@ set(CODEGEN codegen) + + if(CC_GP) + set(CODETYPE trustzone) +- execute_process(COMMAND uuidgen -r +- OUTPUT_VARIABLE UUID) +- string(REPLACE "\n" "" UUID ${UUID}) ++ set(UUID 9cb38838-2766-42be-8b7b-0d184a996066) + add_definitions(-DPATH="/data/${UUID}.sec") + endif() + +diff --git a/examples/seal_data/enclave/CMakeLists.txt b/examples/seal_data/enclave/CMakeLists.txt +index 0ddcbd5..b24e498 100644 +--- a/examples/seal_data/enclave/CMakeLists.txt ++++ b/examples/seal_data/enclave/CMakeLists.txt +@@ -52,7 +52,6 @@ set(COMMON_C_FLAGS "-W -Wall -Werror -fno-short-enums -fno-omit-frame-pointer + set(COMMON_C_LINK_FLAGS "-Wl,-z,now -Wl,-z,relro -Wl,-z,noexecstack -Wl,-nostdlib -nodefaultlibs -nostartfiles") + + if(CC_GP) +- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt.in" "${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt") + set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} -march=armv8-a ") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s") + set(CMAKE_SHARED_LINKER_FLAGS "${COMMON_C_LINK_FLAGS} -Wl,-s -fPIC") +@@ -67,6 +66,7 @@ if(CC_GP) + + target_include_directories( ${PREFIX} PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} ++ ${LOCAL_ROOT_PATH}/debug/inc + ${LOCAL_ROOT_PATH}/inc/host_inc + ${LOCAL_ROOT_PATH}/inc/host_inc/gp + ${LOCAL_ROOT_PATH}/inc/enclave_inc +@@ -91,15 +91,14 @@ if(CC_GP) + endforeach(WHITE_LIST) + + target_link_libraries(${PREFIX} -lsecgear_tee) +- +- add_custom_command(TARGET ${PREFIX} +- POST_BUILD +- COMMAND bash ${SIGN_TOOL} -d sign -x trustzone -a 2 -i ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${PREFIX}.so -c ${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt +- -o ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT}) +- +- install(FILES ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT} +- DESTINATION /data +- PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) ++ # for trustzone compiling, you should connact us to get config and private_key.pem for test, so we will not sign and install binary in this example # ++ # add_custom_command(TARGET ${PREFIX} ++ # POST_BUILD ++ # COMMAND bash ${SIGN_TOOL} -d sign -x trustzone -i ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${PREFIX}.so -c ${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt -m ${CMAKE_CURRENT_SOURCE_DIR}/config_cloud.ini -o ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT}) ++ ++ # install(FILES ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT} ++ # DESTINATION /data ++ # PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + + endif() + +diff --git a/examples/seal_data/enclave/config_cloud.ini b/examples/seal_data/enclave/config_cloud.ini +new file mode 100644 +index 0000000..f0c0e39 +--- /dev/null ++++ b/examples/seal_data/enclave/config_cloud.ini +@@ -0,0 +1,49 @@ ++[config] ++;0 means debug ++;1 means release ++;[fixed value] ++releaseType = 1 ++;;; ++;0 means TA not installed by OTRP ++;1 means TA installed by OTRP ++otrpFlag = 0 ++;;; ++;server address for signing TA ++serverIp= ++;;; ++;public key for encrypt TA ++;[fixed value] ++encryptKey = cloud/rsa_public_key_cloud.pem ++;;; ++;public key length ++;[fixed value] ++encryptKeyLen = 3072 ++;;; ++;0 means not sign ++;1 means signed by local private ++;2 means signed using native sign tool; ++;3 means signed by CI ++;[fixed value] ++signType = 1 ++;;; ++;private key for signing TA ++;[private key owned by yourself] ++signKey = ../../examples/seal_data/enclave/cert/private_key.pem ++;;; ++;private key length for signing TA ++;[key length should be 4096 for security enhance] ++signKeyLen = 4096 ++;;; ++;0 means SHA256 hash type ++;1 means SHA512 hash type ++;[set value to 0 by default] ++hashType = 0 ++;;; ++;0 means padding type is pkcs1v15 ++;1 means padding type is PSS ++;[set value to 0 by default] ++paddingType = 0 ++;;; ++;config file ++;[signed config file by Huawei] ++configPath= ../../examples/seal_data/enclave/signed_config/config +diff --git a/examples/seal_data/enclave/manifest.txt b/examples/seal_data/enclave/manifest.txt +new file mode 100644 +index 0000000..e845fd7 +--- /dev/null ++++ b/examples/seal_data/enclave/manifest.txt +@@ -0,0 +1,7 @@ ++gpd.ta.appID: 9cb38838-2766-42be-8b7b-0d184a996066 ++gpd.ta.service_name: secstorage-demo ++gpd.ta.singleInstance: true ++gpd.ta.multiSession: false ++gpd.ta.instanceKeepAlive: False ++gpd.ta.dataSize: 819200 ++gpd.ta.stackSize: 40960 +diff --git a/examples/seal_data/enclave/manifest.txt.in b/examples/seal_data/enclave/manifest.txt.in +deleted file mode 100644 +index 749815a..0000000 +--- a/examples/seal_data/enclave/manifest.txt.in ++++ /dev/null +@@ -1,8 +0,0 @@ +-gpd.ta.appID: @UUID@ +-gpd.ta.service_name: seal_data +-gpd.ta.singleInstance: true +-gpd.ta.multiSession: false +-gpd.ta.multiCommand: false +-gpd.ta.instanceKeepAlive: false +-gpd.ta.dataSize: 4038400 +-gpd.ta.stackSize: 6048000 +diff --git a/examples/seal_data/host/CMakeLists.txt b/examples/seal_data/host/CMakeLists.txt +index 75b33f7..691cd07 100644 +--- a/examples/seal_data/host/CMakeLists.txt ++++ b/examples/seal_data/host/CMakeLists.txt +@@ -40,6 +40,7 @@ if(CC_GP) + endif() + add_executable(${OUTPUT} ${SOURCE_FILE} ${AUTO_FILES}) + target_include_directories(${OUTPUT} PRIVATE ++ ${LOCAL_ROOT_PATH}/debug/inc + ${LOCAL_ROOT_PATH}/inc/host_inc + ${LOCAL_ROOT_PATH}/inc/host_inc/gp + ${CMAKE_CURRENT_BINARY_DIR}) +diff --git a/src/enclave_src/gp/itrustee/itrustee_seal_data.c b/src/enclave_src/gp/itrustee/itrustee_seal_data.c +index 5b1676a..cf13bd9 100644 +--- a/src/enclave_src/gp/itrustee/itrustee_seal_data.c ++++ b/src/enclave_src/gp/itrustee/itrustee_seal_data.c +@@ -221,12 +221,11 @@ TEE_Result itrustee_unseal_data(void *sealed_data, uint8_t *decrypted_data, uint + SLogError("malloc key_buf failed\n"); + return TEE_ERROR_OUT_OF_MEMORY; + } +- result = TEE_EXT_DeriveTARootKey(salt, strlen(salt), key_buf, key_len); ++ result = TEE_EXT_DeriveTARootKey(salt, SEAL_KEY_SALT_LEN, key_buf, key_len); + if (result != TEE_SUCCESS) { + SLogError("DeriveTARootKey failed"); + goto done; + } +- + *decrypted_data_len = tmp_sealed_data->encrypted_data_len; + *mac_data_len = tmp_sealed_data->aad_len; + result = aes_seal_unseal_data(key_buf, key_len, (uint8_t *)&(tmp_sealed_data->nonce), SEAL_DATA_NONCE_LEN, +diff --git a/src/host_src/gp/CMakeLists.txt b/src/host_src/gp/CMakeLists.txt +index 37635ec..ca6d87f 100644 +--- a/src/host_src/gp/CMakeLists.txt ++++ b/src/host_src/gp/CMakeLists.txt +@@ -11,8 +11,6 @@ + set(gp_engine gp_0) + + # to do itrustee sdk Open Source +-set(itrustee_lib ) +- + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/gp) + + if(${CMAKE_VERSION} VERSION_LESS "3.13.0") +@@ -33,7 +31,7 @@ endif() + + set_target_properties(${gp_engine} PROPERTIES SKIP_BUILD_RPATH TRUE) + #link iTrustee teec lib +-target_link_libraries(${gp_engine} ${itrustee_lib} secgear pthread) ++target_link_libraries(${gp_engine} secgear pthread teec_adaptor) + + install(TARGETS ${gp_engine} + LIBRARY +diff --git a/src/host_src/gp/gp_enclave.c b/src/host_src/gp/gp_enclave.c +index b185958..86ea941 100644 +--- a/src/host_src/gp/gp_enclave.c ++++ b/src/host_src/gp/gp_enclave.c +@@ -25,7 +25,7 @@ + + #define OCALL_AGENT_REGISTER_SUCCESS 0 + #define OCALL_AGENT_REGISTER_FAIL 1 +- ++#define SECGEAR_OCALL 0 + #define MAX_LEN 4096 + + static pthread_cond_t g_cond = PTHREAD_COND_INITIALIZER; +@@ -535,7 +535,7 @@ cc_enclave_result_t cc_enclave_call_function( + /* for ocall thread */ + ires = pthread_mutex_lock(&g_mtx_flag); + SECGEAR_CHECK_MUTEX_RES(ires); +- if (!(g_list_ops.pthread_flag)) { ++ if (g_list_ops.pthread_flag || SECGEAR_OCALL) { + param.agent_id = *(uint32_t *)ms; + param.num = ((ocall_enclave_table_t *)ocall_table)->num; + param.ocalls = ((ocall_enclave_table_t *)ocall_table)->ocalls; +diff --git a/tools/sign_tool/rsa_public_key_cloud.pem b/tools/sign_tool/cloud/rsa_public_key_cloud.pem +similarity index 100% +rename from tools/sign_tool/rsa_public_key_cloud.pem +rename to tools/sign_tool/cloud/rsa_public_key_cloud.pem +diff --git a/tools/sign_tool/generate_signature.py b/tools/sign_tool/generate_signature.py +new file mode 100644 +index 0000000..b3264ba +--- /dev/null ++++ b/tools/sign_tool/generate_signature.py +@@ -0,0 +1,56 @@ ++#!/usr/bin/env python ++# coding:utf-8 ++#---------------------------------------------------------------------------- ++# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. ++# iTrustee 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: tools for generating a trusted application load image ++# Author: Li mingjuan ++# Create: 2020-10-27 ++#---------------------------------------------------------------------------- ++ ++import struct ++import os ++import hashlib ++import subprocess ++ ++HASH256 = 0 ++HASH512 = 1 ++ ++def gen_hash(hash_type, in_file_path, out_file_path): ++ in_file_size = os.path.getsize(in_file_path) ++ # Initialize a SHA256 object from the Python hash library ++ if int(hash_type) == HASH256: ++ hash_op = hashlib.sha256() ++ elif int(hash_type) == HASH512: ++ hash_op = hashlib.sha512() ++ # Set the input buffer and return the output digest ++ with open(in_file_path, 'rb') as in_file: ++ hash_op.update(in_file.read(in_file_size)) ++ ++ #-----hash file used for ras sign--- ++ with open(out_file_path, 'wb') as hash_fp: ++ # fixed hash prefix value ++ hash_fp.write(struct.pack('B'*19, 0x30, 0x31, 0x30, 0x0d, 0x06, \ ++ 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, \ ++ 0x05, 0x00, 0x04, 0x20)) ++ hash_fp.write(hash_op.digest()) ++ return ++ ++def gen_ta_signature(cfg, hash_file_path, out_file_path): ++ cmd = "openssl rsautl -sign -inkey {} -in {} -out {}".\ ++ format(cfg.sign_key, hash_file_path, out_file_path) ++ try: ++ subprocess.check_output(cmd.split(), shell=False) ++ except Exception: ++ print("sign operation failed") ++ raise RuntimeError ++ return ++ +diff --git a/tools/sign_tool/manifest.py b/tools/sign_tool/manifest.py +index 4de8407..9cc2360 100644 +--- a/tools/sign_tool/manifest.py ++++ b/tools/sign_tool/manifest.py +@@ -1,10 +1,20 @@ + #!/usr/bin/env python + # coding:utf-8 + #---------------------------------------------------------------------------- +-# Copyright @ Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. +-# tools for generating a trusted application load image ++# Copyright (c) Huawei Technologies Co., Ltd. 2018-2020. All rights reserved. ++# iTrustee 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: tools for generating a trusted application load image ++# Author: Li mingjuan ++# Create: 2018-02-20 + #---------------------------------------------------------------------------- +- + import string + import struct + import uuid +@@ -14,31 +24,32 @@ PRODUCT_TA_IMAGE = 1 + PRODUCT_DYN_LIB = 2 + PRODUCT_SERVICE_IMAGE = 3 + +-class TEE_UUID: ++ ++class PackUuid: + # Structure object to align and package the TEE_UUID +- s = struct.Struct('IHH8b') ++ data = struct.Struct('IHH8b') + + def __init__(self, data): +- unpacked_data = (TEE_UUID.s).unpack(str.encode(data)) ++ unpacked_data = (PackUuid.data).unpack(str.encode(data)) + self.unpacked_data = unpacked_data +- self.timeLow = unpacked_data[0] +- self.timeMid = unpacked_data[1] +- self.timeHiAndVersion = unpacked_data[2] +- self.clockSeqAndNode = unpacked_data[3] ++ self.time_low = unpacked_data[0] ++ self.time_mid = unpacked_data[1] ++ self.time_hi_version = unpacked_data[2] ++ self.clock_seq_node = unpacked_data[3] + +- def printValues(self): ++ def print_values(self): + print("ATTRIBUTE / VALUE") + for attr, value in self.__dict__.items(): + print(attr, value) + +- def getPackedData(self): +- values = [self.timeLow, +- self.timeMid, +- self.timeHiAndVersion, +- self.clockSeqAndNode, ++ def get_pack_data(self): ++ values = [self.time_low, ++ self.time_mid, ++ self.time_hi_version, ++ self.clock_seq_node, + ] + +- return (TEE_UUID.s).pack(*values) ++ return (PackUuid.data).pack(*values) + + + #---------------------------------------------------------------------------- +@@ -47,10 +58,10 @@ class TEE_UUID: + class Manifest: + + # Structure object to align and package the Manifest +- s = struct.Struct('I' * 6) ++ data = struct.Struct('I' * 6) + + def __init__(self, data): +- unpacked_data = (Manifest.s).unpack(str.encode(data)) ++ unpacked_data = (Manifest.data).unpack(str.encode(data)) + self.unpacked_data = unpacked_data + self.single_instance = unpacked_data[0] + self.multi_session = unpacked_data[1] +@@ -59,12 +70,12 @@ class Manifest: + self.stack_size = unpacked_data[4] + self.instancekeepalive = unpacked_data[5] + +- def printValues(self): ++ def print_values(self): + print("ATTRIBUTE / VALUE") + for attr, value in self.__dict__.items(): + print(attr, value) + +- def getPackedData(self): ++ def get_pack_data(self): + values = [self.single_instance, + self.multi_session, + self.multi_command, +@@ -73,21 +84,22 @@ class Manifest: + self.instancekeepalive, + ] + +- return (Manifest.s).pack(*values) ++ return (Manifest.data).pack(*values) ++ + + #---------------------------------------------------------------------------- + # verify property name in manifest file + #---------------------------------------------------------------------------- +-def verify_property_name(strLine): ++def verify_property_name(str_line): + print('verify property name') + alphas = string.ascii_letters + string.digits + cont = "".join([alphas, '-', '_', '.']) +- if len(strLine) > 1: +- if strLine[0] not in alphas: ++ if len(str_line) > 1: ++ if str_line[0] not in alphas: + print('invalid first letter in property name') + return False + else: +- for otherchar in strLine[1:]: ++ for otherchar in str_line[1:]: + if otherchar not in cont: + print('invalid char in property name') + return False +@@ -97,35 +109,37 @@ def verify_property_name(strLine): + + return True + ++ + #---------------------------------------------------------------------------- + # verify property value in manifest file + #---------------------------------------------------------------------------- +-def verify_property_value(strLine): ++def verify_property_value(str_line): + print('verify property value') +- filt_letter = chr(0) + chr(10) +chr(13) +- for thechar in strLine: ++ filt_letter = chr(0) + chr(10) + chr(13) ++ for thechar in str_line: + if thechar in filt_letter: + print('invalid letter in prop value') + return False + return True + ++ + #---------------------------------------------------------------------------- + # remove tabs and space in property value + #---------------------------------------------------------------------------- +-def trailing_space_tabs(strLine): ++def trailing_space_tabs(str_line): + print('trailing space tabs in value head and trail') +- space_tabs = chr(9) + chr(32) +chr(160) +- space_tabs_newlines = space_tabs + chr(10) +chr(13) ++ space_tabs = chr(9) + chr(32) + chr(160) ++ space_tabs_newlines = space_tabs + chr(10) + chr(13) + print('tab: {}'.format(space_tabs)) + +- print('str in: {}'.format(strLine)) ++ print('str in: {}'.format(str_line)) + index = 0 +- for thechar in strLine: ++ for thechar in str_line: + if thechar in space_tabs: + index += 1 + else: + break +- headvalue = strLine[index:] ++ headvalue = str_line[index:] + + strlen = len(headvalue) + +@@ -137,21 +151,20 @@ def trailing_space_tabs(strLine): + else: + break + +- #print 'str len: '+str(strlen) +- strRet = headvalue[0:strlen+1] + chr(10) +- print('str ret: {}'.format(strRet)) ++ str_ret = headvalue[0:strlen+1] + chr(10) ++ print('str ret: {}'.format(str_ret)) ++ ++ return str_ret + +- return strRet + + #---------------------------------------------------------------------------- + # verify manifest file, parse manifest file, generate a new manfiest file + #---------------------------------------------------------------------------- +-def parserManifest(manifest, manifestDataPath, mani_ext): ++def parser_manifest(manifest, manifest_data_path, mani_ext): + print('verify manifest') +- targetType = PRODUCT_TA_IMAGE ++ target_type = PRODUCT_TA_IMAGE + +- uuid_val_flag = 1 +- uuid_val = TEE_UUID('\0' * 16) ++ uuid_val = PackUuid('\0' * 16) + + #manifest default + manifest_val = Manifest('\0'*24) +@@ -166,30 +179,29 @@ def parserManifest(manifest, manifestDataPath, mani_ext): + service_name = 'external_service' + + with open(manifest, 'r') as mani_fp, open(mani_ext, 'wb') as mani_ext_fp: +- for eachLine in mani_fp: +- print(eachLine) +- if eachLine.startswith("#") or not len(eachLine.strip()): ++ for each_line in mani_fp: ++ print(each_line) ++ if each_line.startswith("#") or not len(each_line.strip()): + continue +- index = eachLine.find(':', 1, len(eachLine)) +- #print 'index name : value is ' + str(index) ++ index = each_line.find(':', 1, len(each_line)) + +- prop_name = eachLine[0:index] #no ':' +- prop_name_t = eachLine[0:index+1] #with ':' +- prop_value_t = eachLine[index+1:] ++ prop_name = each_line[0:index] ++ prop_name_t = each_line[0:index+1] ++ prop_value_t = each_line[index+1:] + print('name is: {}; value is: {}'.format(prop_name, prop_value_t)) + + prop_value = trailing_space_tabs(prop_value_t) + prop_len = len(prop_value) +- prop_value_v = prop_value[0:prop_len-1]# mv last letter ++ prop_value_v = prop_value[0:prop_len-1] + print('prop value_v: {}'.format(prop_value_v)) + + if verify_property_name(prop_name) is False: + print('manifest format invalid, please check it') +- return (False, 0, 0, 0) ++ return (False, 0) + + if verify_property_value(prop_value_v) is False: + print('manifest format invalid, please check it') +- return (False, 0, 0, 0) ++ return (False, 0) + + # name:value to lowcase, and parse manifest + prop_name_low = prop_name.lower() +@@ -197,58 +209,54 @@ def parserManifest(manifest, manifestDataPath, mani_ext): + if 'gpd.ta.appid' == prop_name_low: + print("compare name is srv id") + uuid_val = uuid.UUID(prop_value_v) +- uuid_val_flag = 0 + print('uuid str {}'.format(uuid_val)) + print('val fields {}'.format(uuid_val.fields)) + + elif 'gpd.ta.singleinstance' == prop_name_low: + prop_value_low = prop_value_v.lower() + if 'true' == prop_value_low: +- manifest_val.single_instance = 1; ++ manifest_val.single_instance = 1 + elif 'false' == prop_value_low: +- manifest_val.single_instance = 0; ++ manifest_val.single_instance = 0 + else: + print('single_instance value error!') + + elif 'gpd.ta.multisession' == prop_name_low: + prop_value_low = prop_value_v.lower() + if 'true' == prop_value_low: +- manifest_val.multi_session = 1; ++ manifest_val.multi_session = 1 + elif 'false' == prop_value_low: +- manifest_val.multi_session = 0; ++ manifest_val.multi_session = 0 + else: + print('multi_session value error!') + + elif 'gpd.ta.multicommand' == prop_name_low: + prop_value_low = prop_value_v.lower() + if 'true' == prop_value_low: +- manifest_val.multi_command = 1; ++ manifest_val.multi_command = 1 + elif 'false' == prop_value_low: +- manifest_val.multi_command = 0; ++ manifest_val.multi_command = 0 + else: + print('multi_command value error!') + + elif 'gpd.ta.instancekeepalive' == prop_name_low: + prop_value_low = prop_value_v.lower() + if 'true' == prop_value_low: +- manifest_val.instancekeepalive = 1; ++ manifest_val.instancekeepalive = 1 + elif 'false' == prop_value_low: +- manifest_val.instancekeepalive = 0; ++ manifest_val.instancekeepalive = 0 + else: + print('instancekeepalive value error!') + + elif 'gpd.ta.datasize' == prop_name_low: +- #manifest_val.heap_size = prop_value_v.atoi() + manifest_val.heap_size = int(prop_value_v) + print('b') + + elif 'gpd.ta.stacksize' == prop_name_low: +- #manifest_val.stack_size = prop_value_v.atoi() + manifest_val.stack_size = int(prop_value_v) + print('b') + + elif 'gpd.ta.service_name' == prop_name_low: +- #manifest_val.stack_size = prop_value_v.atoi() + service_name = prop_value_v + print('b') + +@@ -260,11 +268,11 @@ def parserManifest(manifest, manifestDataPath, mani_ext): + if 'gpd.ta.is_tee_service' == prop_name_low: + prop_value_low = prop_value_v.lower() + if 'true' == prop_value_low: +- targetType = PRODUCT_SERVICE_IMAGE ++ target_type = PRODUCT_SERVICE_IMAGE + elif 'gpd.ta.is_lib' == prop_name_low: + prop_value_low = prop_value_v.lower() + if 'true' == prop_value_low: +- targetType = PRODUCT_DYN_LIB ++ target_type = PRODUCT_DYN_LIB + + #write the whole parsed manifest into sample.manifest file + +@@ -277,14 +285,11 @@ def parserManifest(manifest, manifestDataPath, mani_ext): + + # get manifest string file len + manifest_str_size = os.path.getsize(mani_ext) +- if manifest_str_size > 152: +- print("extra manifest string exceed MAX len 152") +- raise RuntimeError + print('manifest str size {}'.format(manifest_str_size)) + + # 2> manifest + service_name + print("bytes len {}".format(len(uuid_val.bytes_le))) +- print("bytes len {}".format(len(manifest_val.getPackedData()))) ++ print("bytes len {}".format(len(manifest_val.get_pack_data()))) + print("bytes len {}".format(len(service_name))) + + # 3> unparsed manifest, string manifest +@@ -294,23 +299,24 @@ def parserManifest(manifest, manifestDataPath, mani_ext): + print("manifest strint: {}".format(manifest_string_buf)) + + #---- write manifest parse context to manifest file +- with open(manifestDataPath, 'wb') as out_manifest_fp: ++ with open(manifest_data_path, 'wb') as out_manifest_fp: + out_manifest_fp.write(uuid_val.bytes_le) + out_manifest_fp.write(str.encode(service_name)) +- out_manifest_fp.write(manifest_val.getPackedData()) ++ out_manifest_fp.write(manifest_val.get_pack_data()) + +- productName = str(uuid_val) +- if targetType == PRODUCT_TA_IMAGE: ++ product_name = str(uuid_val) ++ if target_type == PRODUCT_TA_IMAGE: + print("product type is ta image") +- productName = "".join([productName, ".sec"]) +- elif targetType == PRODUCT_SERVICE_IMAGE: ++ product_name = "".join([product_name, ".sec"]) ++ elif target_type == PRODUCT_SERVICE_IMAGE: + print("product type is service") +- productName = "".join([productName, service_name, "_svr.sec"]) +- elif targetType == PRODUCT_DYN_LIB: ++ product_name = "".join([product_name, service_name, "_svr.sec"]) ++ elif target_type == PRODUCT_DYN_LIB: + print("product type is dyn lib") +- productName = "".join([productName, service_name, ".so.sec"]) ++ product_name = "".join([product_name, service_name, ".so.sec"]) + else: + print("invalid product type!") + raise RuntimeError + +- return (True, productName, uuid_val_flag) ++ return (True, product_name) ++ +diff --git a/tools/sign_tool/sign_tool.py b/tools/sign_tool/sign_tool.py +deleted file mode 100644 +index 1e6e37d..0000000 +--- a/tools/sign_tool/sign_tool.py ++++ /dev/null +@@ -1,471 +0,0 @@ +-#!/usr/bin/env python +-# coding:utf-8 +-#---------------------------------------------------------------------------- +-# Copyright @ Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. +-# tools for generating a trusted application load image +-#---------------------------------------------------------------------------- +- +-import struct +-import sys +-import os +-import hashlib +-import binascii +-import subprocess +-import shutil +- +-from manifest import * +- +-DEBUG = 0 +-VERSION = 3 +-TA_VERSION = 3 +-# TA_TYPE 1 stand for v3.0 +-# TA_TYPE 2 stand for v3.1(with config and cert) +-TA_TYPE = 0 +- +-API_LEVEL = 1 +-PRODUCT_NAME = "" +- +-# OTRP_FLAG 1 stand for otrp sec, and only can load sec by otrp mode +-# OTRP_FLAG 0 stand for no-otrp sec, and only can load sec by tzdriver mode +-OTRP_FLAG = 0 +- +-MAGIC1 = 0xA5A55A5A +-MAGIC2 = 0x55AA +- +-# low 8 bits:key is derived from root key +-# high 8 bits:key len is 3072, if value is 0 or 1, then key len is 2048 +-KEY_VERSION = 0x0202 +- +-SIGN_ALG_V3 = 0x10002048 +-SIGN_ALG_V4 = 0x10004096 +- +-HASH256_LEN = 256 +-HASH512_LEN = 512 +- +-ENCRYPTED_KEYINFO_LEN =256 +-SIGNATURE_LEN_256 = 256 +-SIGNATURE_LEN_512 = 512 +- +-SUCCESS = 0 +- +-# ELF Definitions +-ELF_TYPE = 32 +-ELF_HDR_SIZE = 52 +-ELF_PHDR_SIZE = 32 +-ELF_INFO_MAGIC0_INDEX = 0 +-ELF_INFO_MAGIC1_INDEX = 1 +-ELF_INFO_MAGIC2_INDEX = 2 +-ELF_INFO_MAGIC3_INDEX = 3 +-ELF_INFO_MAGIC0 = 127 #'\x7f' +-ELF_INFO_MAGIC1 = 69 #'E' +-ELF_INFO_MAGIC2 = 76 #'L' +-ELF_INFO_MAGIC3 = 70 #'F' +-ELF_INFO_CLASS_INDEX = 4 +-ELF_INFO_CLASS = 1 #'\x01' +-ELF_INFO_VERSION_INDEX = 6 +-ELF_INFO_VERSION_CURRENT = 1 #'\x01' +-ELF_BLOCK_ALIGN = 0x1000 +-ELF_HEAD_FORMAT = '' +- +-#---------------------------------------------------------------------------- +-# ELF File Header Check +-#---------------------------------------------------------------------------- +-class Elf_Header: +- def __init__(self, data): +- # Algin data obj in ELF header +- if(ELF_TYPE == 64): +- self.s = struct.Struct('16sHHIQQQIHHHHHH') +- else: +- self.s = struct.Struct('16sHHIIIIIHHHHHH') +- +- unpacked_data = (self.s).unpack(data) +- self.unpacked_data = unpacked_data +- self.elf_ident = unpacked_data[0] +- self.elf_type = unpacked_data[1] +- self.elf_machine = unpacked_data[2] +- self.elf_version = unpacked_data[3] +- self.elf_entry = unpacked_data[4] +- self.elf_phoff = unpacked_data[5] +- self.elf_shoff = unpacked_data[6] +- self.elf_flags = unpacked_data[7] +- self.elf_ehsize = unpacked_data[8] +- self.elf_phentsize = unpacked_data[9] +- self.elf_phnum = unpacked_data[10] +- self.elf_shentsize = unpacked_data[11] +- self.elf_shnum = unpacked_data[12] +- self.elf_shstrndx = unpacked_data[13] +- +- def printValues(self): +- print("ATTRIBUTE / VALUE") +- for attr, value in self.__dict__.items(): +- print(attr, value) +- +- def getPackedData(self): +- values = [self.elf_ident, +- self.elf_type, +- self.elf_machine, +- self.elf_version, +- self.elf_entry, +- self.elf_phoff, +- self.elf_shoff, +- self.elf_flags, +- self.elf_ehsize, +- self.elf_phentsize, +- self.elf_phnum, +- self.elf_shentsize, +- self.elf_shnum, +- self.elf_shstrndx +- ] +- +- return (self.s).pack(*values) +- +-#---------------------------------------------------------------------------- +-# Verify ELF header contents from an input ELF file +-#---------------------------------------------------------------------------- +-def verify_elf_header(elf_header): +- s = struct.unpack('BBBBBBBBBBBBBBBB', elf_header.elf_ident) +- if (s[ELF_INFO_MAGIC0_INDEX] != ELF_INFO_MAGIC0) or \ +- (s[ELF_INFO_MAGIC1_INDEX] != ELF_INFO_MAGIC1) or \ +- (s[ELF_INFO_MAGIC2_INDEX] != ELF_INFO_MAGIC2) or \ +- (s[ELF_INFO_MAGIC3_INDEX] != ELF_INFO_MAGIC3) or \ +- (s[ELF_INFO_CLASS_INDEX] != ELF_INFO_CLASS) or \ +- (s[ELF_INFO_VERSION_INDEX] != ELF_INFO_VERSION_CURRENT): +- +- return False +- else: +- return True +- +-def get_elf_type(elfFile): +- EI_NIDENT = 16 +- global ELF_TYPE +- global ELF_HDR_SIZE +- global ELF_HEAD_FORMAT +- global ELF_INFO_CLASS +- +- elfFile.seek(0x0, 0) +- elf_ident = elfFile.read(EI_NIDENT) +- ''' check EI_CLASS, 32-bit or 64-bit''' +- elfStr = bytes.decode(elf_ident) +- s = struct.unpack('BBBBBBBBBBBBBBBB', elf_ident) +- if s[4] == 2: +- print("64 bit type") +- ELF_TYPE = 64 +- ELF_HDR_SIZE = 64 +- ELF_HEAD_FORMAT = "HHIQQQIHHHHHH" +- ELF_INFO_CLASS = 2 +- elif s[4] == 1: +- print("32 bit type") +- ELF_TYPE = 32 +- ELF_HDR_SIZE = 52 +- ELF_HEAD_FORMAT = "HHIIIIIHHHHHH" +- ELF_INFO_CLASS = 1 +- else: +- raise RuntimeError("Unknown ELF file type") +- return +- +-def generateHeader(contentLen): +- return struct.pack('IHHII', MAGIC1, MAGIC2, VERSION, contentLen, KEY_VERSION) +- +-def generateAesKeyInfo(ivFilePath, keyFilePath, outFilePath): +- # Aes key is randomly generated and temporarily stored in the file in plaintext, please ensure security. +- try: +- subprocess.check_output(["openssl", "rand", "-out", format(ivFilePath), "16"], shell=False) +- subprocess.check_output(["openssl", "rand", "-out", format(keyFilePath), "32"], shell=False) +- except: +- print("rand operation failed") +- raise RuntimeError +- +- with open(outFilePath, 'wb') as outFile: +- outFile.write(struct.pack('I', 32)) +- outFile.write(struct.pack('I', 16)) +- if DEBUG == 0 or TA_TYPE == 1: +- outFile.write(struct.pack('I', SIGN_ALG_V3)) +- elif TA_TYPE == 2: +- outFile.write(struct.pack('I', SIGN_ALG_V4)) +- else: +- print("target sign type is not supported: {}".format(TA_TYPE)) +- raise RuntimeError +- +- with open(keyFilePath, 'rb') as keyFile: +- outFile.write(keyFile.read(32)) +- +- with open(ivFilePath, 'rb') as ivFile: +- outFile.write(ivFile.read(16)) +- +- return +- +-def encryptAesKeyInfo(pubkeyFilePath, inFilePath, outFilePath): +- try: +- subprocess.check_output(["openssl", "rsautl", "-encrypt", "-pubin", "-oaep", \ +- "-inkey", format(pubkeyFilePath), "-in", format(inFilePath), "-out", format(outFilePath)], shell=False) +- except: +- print("RSA encrypt operation failed") +- raise RuntimeError +- return +- +-def generateHash(hashLen, inFilePath, outFilePath): +- inFileSize = os.path.getsize(inFilePath) +- # Initialize a SHA256 object from the Python hash library +- if hashLen == HASH256_LEN: +- hashOp = hashlib.sha256() +- elif hashLen == HASH512_LEN: +- hashOp = hashlib.sha512() +- # Set the input buffer and return the output digest +- with open(inFilePath, 'rb') as inFile: +- hashOp.update(inFile.read(inFileSize)) +- +- #-----hash file used for ras sign--- +- with open(outFilePath, 'wb') as hash_fp: +- # fixed hash prefix value +- hash_fp.write(struct.pack('B'*19, 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, +- 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20)) +- hash_fp.write(hashOp.digest()) +- return +- +-def generateSignature(priKeyPath, inFilePath, outFilePath): +- if TA_TYPE == 1: +- print("generate dummy signature for DEBUG version") +- with open(outFilePath, 'wb') as f: +- f.write(str.encode('\0'*256, encoding='utf-8')) +- elif TA_TYPE == 2: +- try: +- subprocess.check_output(["openssl", "rsautl", "-sign", "-inkey", format(priKeyPath), \ +- "-in", format(inFilePath), " -out", format(outFilePath)], shell=False) +- except: +- print("sign operation failed") +- raise RuntimeError +- return +- +-def checkSignature(rawDataHashPath, inSignature, serverPubKey): +- try: +- subprocess.check_output(["openssl", "pkeyutl", "-verify", "-in", format(rawDataHashPath), \ +- "-sigfile", format(inSignature), "-pubin", "-inkey", format(serverPubKey)], shell=False) +- except: +- print("check operation failed") +- raise RuntimeError +- return +- +-def generateRawData(manifestDataPath, manifestExtFilePath, elfFilePath, configFilePath, rawFilePath): +- manifestDataSize = os.path.getsize(manifestDataPath) +- manifestExtSize = os.path.getsize(manifestExtFilePath) +- elfFileSize = os.path.getsize(elfFilePath) +- configFileSize = 0 +- +- with open(rawFilePath, 'wb') as f: +- header = "" +- if TA_TYPE == 2: +- configFileSize = os.path.getsize(configFilePath) +- header = struct.pack('IIIII', TA_VERSION, manifestDataSize, manifestExtSize, elfFileSize, configFileSize) +- f.write(header) +- +- with open(manifestDataPath, 'rb') as manifestData: +- f.write(manifestData.read(manifestDataSize)) +- +- with open(manifestExtFilePath, 'rb') as manifestExt: +- f.write(manifestExt.read(manifestExtSize)) +- +- with open(elfFilePath, 'rb') as elfFile: +- get_elf_type(elfFile) +- elfFile.seek(0x0, 0) +- elfFileHaderBuf = elfFile.read(ELF_HDR_SIZE) +- elfFileHader = Elf_Header(elfFileHaderBuf) +- if verify_elf_header(elfFileHader) is False: +- print("verify elf header failed") +- raise RuntimeError +- elfFile.seek(0x0, 0) +- f.write(elfFile.read(elfFileSize)) +- +- if TA_TYPE == 2: +- with open(configFilePath, 'rb') as configFile: +- f.write(configFile.read(configFileSize)) +- return +- +-def aesEncrypt(keyPath, ivPath, inFilePath, outfilePath): +- keySize = os.path.getsize(keyPath) +- with open(keyPath, 'rb') as key: +- keyData = key.read(keySize) +- hexKeyStr = binascii.b2a_hex(keyData) +- +- ivSize = os.path.getsize(ivPath) +- with open(ivPath, 'rb') as iv: +- ivData = iv.read(ivSize) +- hexIvStr = binascii.b2a_hex(ivData) +- +- try: +- subprocess.check_output(["openssl", "enc", "-aes-256-cbc", "-in", format(inFilePath), \ +- "-out", format(outfilePath), "-K", format(bytes.decode(hexKeyStr)), \ +- "-iv", format(bytes.decode(hexIvStr))], shell=False) +- except: +- print("AES encrypt operation failed") +- raise RuntimeError +- +- return +- +-def updateManifestTaApiLevel(manifest): +- line = "\ngpd.ta.api_level:{}\n".format(API_LEVEL) +- with open(manifest, "w") as f: +- f.writelines(line) +- +-def updateManifestTaOtrpFlag(manifest): +- data = '' +- with open(manifest, 'r') as f: +- for line in f: +- if line.startswith("#") or not "gpd.ta.otrp_flag" in line: +- data += line +- line = "\ngpd.ta.otrp_flag:{}\n".format('true') +- data += line +- with open(manifest, "w") as f: +- f.writelines(data) +- +-def generateDataForSign(contentLen, key_info, raw_file, data_sign): +- keyInfoLen = os.path.getsize(key_info) +- rawFileLen = os.path.getsize(raw_file) +- +- with open(data_sign, 'wb') as data_fp, \ +- open(key_info, 'rb') as key_fp, open(raw_file, 'rb') as raw_fp: +- data_fp.write(generateHeader(contentLen)) +- data_fp.write(key_fp.read(keyInfoLen)) +- data_fp.write(raw_fp.read(rawFileLen)) +- +- +-def generateDigest(enclavePath, manifestPath, deviceKeyPath, configFilePath, rawDataHashPath, encKeyInfoFilePath, \ +- encRawFilePath): +- inPath = os.getcwd() +- ivFilePath = os.path.join(inPath, "iv.bin") +- keyFilePath = os.path.join(inPath, "aeskey.bin") +- keyInfoFilePath = os.path.join(inPath, "KeyInfo") +- rawFilePath = os.path.join(inPath, "rawData") +- manifestDataPath = os.path.join(inPath, "manifestData.bin") +- manifestExtPath = os.path.join(inPath, "manifestExt.bin") +- dataForSignPath = os.path.join(inPath, "dataForSign.bin") +- +- #mandentory input files +- manifestFilePath = manifestPath +- elfFilePath = enclavePath +- pubkeyFilePath = deviceKeyPath +- +- (ret, PRODUCT_NAME, flag) = parserManifest(manifestFilePath, manifestDataPath, manifestExtPath) +- updateManifestTaApiLevel(manifestExtPath) +- +- if OTRP_FLAG == 1: +- print("package otrp sec file\n") +- updateManifestTaOtrpFlag(manifestExtPath) +- +- generateRawData(manifestDataPath, manifestExtPath, elfFilePath, configFilePath, rawFilePath) +- +- #generate AES key info to encrypt raw data +- generateAesKeyInfo(ivFilePath, keyFilePath, keyInfoFilePath) +- encryptAesKeyInfo(pubkeyFilePath, keyInfoFilePath, encKeyInfoFilePath) +- +- aesEncrypt(keyFilePath, ivFilePath, rawFilePath, encRawFilePath) +- +- contentLen = 0 +- if DEBUG == 0 or TA_TYPE == 1: +- contentLen = os.path.getsize(encKeyInfoFilePath) + SIGNATURE_LEN_256 + os.path.getsize(encRawFilePath) +- elif TA_TYPE == 2: +- contentLen = os.path.getsize(encKeyInfoFilePath) + SIGNATURE_LEN_512 + os.path.getsize(encRawFilePath) +- else: +- print("target sign type is not supported: {}".format(TA_TYPE)) +- raise RuntimeError +- +- generateDataForSign(contentLen, keyInfoFilePath, rawFilePath, dataForSignPath) +- +- generateHash(HASH256_LEN, dataForSignPath, rawDataHashPath) +- +- #remove temp files +- os.remove(ivFilePath) +- os.remove(keyFilePath) +- os.remove(keyInfoFilePath) +- os.remove(rawFilePath) +- os.remove(manifestDataPath) +- os.remove(manifestExtPath) +- os.remove(dataForSignPath) +- return +- +-def generateSecEnclave(priKeyPath, rawDataHashPath, encKeyInfoFilePath, encRawFilePath, inSignature, serverPubKey, \ +- outFile): +- inPath = os.getcwd() +- signatureFilePath = inSignature +- if DEBUG == 1: +- signatureFilePath = os.path.join(inPath, "signature.bin") +- generateSignature(priKeyPath, rawDataHashPath, signatureFilePath) +- else: +- checkSignature(rawDataHashPath, inSignature, serverPubKey) +- +- contentLen = 0 +- if DEBUG == 0 or TA_TYPE == 1: +- contentLen = os.path.getsize(encKeyInfoFilePath) + SIGNATURE_LEN_256 + os.path.getsize(encRawFilePath) +- elif TA_TYPE == 2: +- contentLen = os.path.getsize(encKeyInfoFilePath) + SIGNATURE_LEN_512 + os.path.getsize(encRawFilePath) +- else: +- print("target sign type is not supported: {}".format(TA_TYPE)) +- raise RuntimeError +- +- # secImagePath = os.path.join(outPath, productName) +- secImagePath = outFile +- with open(secImagePath, 'wb') as secImage: +- # write to sec file [1.header info] +- secImage.write(generateHeader(contentLen)) +- # write to sec file [2.AES key info] +- encKeyInfoSize = os.path.getsize(encKeyInfoFilePath) +- with open(encKeyInfoFilePath, 'rb') as encKeyInfo: +- secImage.write(encKeyInfo.read(encKeyInfoSize)) +- # write to sec file [3.signature] +- signatureSize = os.path.getsize(signatureFilePath) +- with open(signatureFilePath, 'rb') as signatureFile: +- secImage.write(signatureFile.read(signatureSize)) +- # write to sec file [4.encrypted raw data] +- encRawDataSize = os.path.getsize(encRawFilePath) +- with open(encRawFilePath, 'rb') as encRawData: +- secImage.write(encRawData.read(encRawDataSize)) +- +- if DEBUG == 1: +- os.remove(signatureFilePath) +- +- print("=========================SUCCESS============================") +- print("generate TA(V3 format) load image success: ") +- print(secImagePath) +- print("============================================================") +- return +- +-if __name__ == '__main__': +- argvs = sys.argv +- priKeyPath = "" +- configFilePath = "" +- cmd = argvs[1] +- DEBUG = int(argvs[2]) +- enclavePath = argvs[3] +- outFile = argvs[4] +- manifestPath = argvs[5] +- OTRP_FLAG = int(argvs[6]) +- TA_TYPE = int(argvs[7]) +- API_LEVEL = int(argvs[8]) +- DEVICE_PUBKEY = argvs[9] +- configFilePath = argvs[10] +- +- os.umask(127) +- inPath = os.getcwd() +- encKeyInfoFilePath = os.path.join(inPath, "KeyInfo.enc") +- encRawFilePath = os.path.join(inPath, "rawData.enc") +- rawDataHashPath = os.path.join(inPath, "rawDataHash.bin") +- +- if cmd == "digest": +- generateDigest(enclavePath, manifestPath, DEVICE_PUBKEY, configFilePath, rawDataHashPath, encKeyInfoFilePath, \ +- encRawFilePath) +- shutil.copy(rawDataHashPath, outFile) +- elif cmd == "sign": +- if DEBUG == 0: +- inSignature = argvs[11] +- serverPubKey = argvs[12] +- else: +- if TA_TYPE == 2: +- priKeyPath = argvs[11] +- inSignature = "" +- serverPubKey = "" +- generateDigest(enclavePath, manifestPath, DEVICE_PUBKEY, configFilePath, rawDataHashPath, \ +- encKeyInfoFilePath, encRawFilePath) +- generateSecEnclave(priKeyPath, rawDataHashPath, encKeyInfoFilePath, encRawFilePath, inSignature, \ +- serverPubKey, outFile) +- os.remove(rawDataHashPath) +- os.remove(encKeyInfoFilePath) +- os.remove(encRawFilePath) +diff --git a/tools/sign_tool/sign_tool.sh b/tools/sign_tool/sign_tool.sh +index 212db5d..5fd7d5b 100755 +--- a/tools/sign_tool/sign_tool.sh ++++ b/tools/sign_tool/sign_tool.sh +@@ -10,39 +10,42 @@ + + #!/bin/bash + VERSION=3 +-TA_TYPE=1 +-OTRP_FLAG=0 +-API_LEVEL=1 +-DEBUG=0 ++API_LEVEL=2 ++ONE_STEP_MODE=1 ++A_CONFIG_FILE="NULL" + + localpath="$(cd "$(dirname "$0")"; pwd)" + + print_help(){ + echo "sign tool usage: ./sign_tool.sh [options] ..." + echo "[options]" +- echo "-a API_LEVEL, indicates trustzone GP API version, defalut is 1." + echo "-c basic config file." + echo "-d sign tool command, sign/digest." + echo " The sign command is used to generate a signed enclave." + echo " The digest command is used to generate a digest value." +- echo "-f OTRP_FLAG, indicates whether the OTRP standard protocol is supported, default is 0." + echo "-i enclave to be signed." +- echo "-k private key required for single-step method, required when trustzone TA_TYPE is 2 or sgx." +- echo "-m additional config for trustzone when TA_TYPE is 2." ++ echo "-k private key required for single-step method" ++ echo "-m additional config_cloud.ini for trustzone." + echo "-o output parameters, the sign command outputs sigend enclave, the digest command outputs" + echo " digest value." + echo "-p signing server public key certificate, required for two-step method." + echo "-s the signed digest value required for two-step method, this parameter is empty to indicate" + echo " single-step method." +- echo "-t trustzone TA_TYPE, default is 1." + echo "-x enclave type, sgx or trustzone." + echo "-h printf help message." + + } + +-while getopts "d:i:x:m:a:f:t:c:k:p:s:o:h" opt ++while getopts "c:d:i:k:m:o:p:s:x:h" opt + do + case $opt in ++ c) ++ if [[ $OPTARG == -* ]]; then ++ echo "Error: parameter for -c is missing or incorrect" ++ exit -1 ++ fi ++ CONFIG_FILE=$OPTARG ++ ;; + d) + if [[ $OPTARG == -* ]]; then + echo "Error: parameter for -d is missing or incorrect" +@@ -58,13 +61,12 @@ do + fi + IN_ENCLAVE=$OPTARG + ;; +- x) ++ k) + if [[ $OPTARG == -* ]]; then +- echo "Error: parameter for -x is missing or incorrect" ++ echo "Error: parameter for -k is missing or incorrect" + exit -1 +- fi +- typeset -l ENCLAVE_TYPE +- ENCLAVE_TYPE=$OPTARG ++ fi ++ SIG_KEY=$OPTARG + ;; + m) + if [[ $OPTARG == -* ]]; then +@@ -73,55 +75,12 @@ do + fi + A_CONFIG_FILE=$OPTARG + ;; +- a) +- if [[ $OPTARG =~ ^[1-3]$ ]]; then +- API_LEVEL=$OPTARG +- else +- if [[ $OPTARG == -* ]]; then +- echo "Error: parameter for -a is missing or incorrect" +- exit -1 +- fi +- echo "Error: illegal API LEVEL" +- exit -1 +- fi +- ;; +- f) +- if [[ $OPTARG =~ ^[0-1]$ ]]; then +- OTRP_FLAG=$OPTARG +- else +- if [[ $OPTARG == -* ]]; then +- echo "Error: parameter for -f is missing or incorrect" +- exit -1 +- fi +- echo "Error: illegal OTRP FLAG" +- exit -1 +- fi +- ;; +- t) +- if [[ $OPTARG =~ ^[1-2]$ ]]; then +- TA_TYPE=$OPTARG +- else +- if [[ $OPTARG == -* ]]; then +- echo "Error: parameter for -t is missing or incorrect" +- exit -1 +- fi +- echo "Error: illegal TA TYPE" +- exit -1 +- fi +- ;; +- c) +- if [[ $OPTARG == -* ]]; then +- echo "Error: parameter for -c is missing or incorrect" +- exit -1 +- fi +- CONFIG_FILE=$OPTARG +- ;; +- k) ++ o) + if [[ $OPTARG == -* ]]; then +- echo "Error: parameter for -k is missing or incorrect" ++ echo "Error: parameter for -o is missing or incorrect" + exit -1 + fi +- SIG_KEY=$OPTARG ++ OUT_FILE=$OPTARG + ;; + p) + if [[ $OPTARG == -* ]]; then +@@ -137,12 +96,13 @@ do + fi + SIGNATURE=$OPTARG + ;; +- o) ++ x) + if [[ $OPTARG == -* ]]; then +- echo "Error: parameter for -o is missing or incorrect" ++ echo "Error: parameter for -x is missing or incorrect" + exit -1 +- fi +- OUT_FILE=$OPTARG ++ fi ++ typeset -l ENCLAVE_TYPE ++ ENCLAVE_TYPE=$OPTARG + ;; + h) + print_help +@@ -160,47 +120,48 @@ fi + + itrustee_start_sign(){ + # check_native_sign +- MANIFEST=$CONFIG_FILE +- if [ -z $MANIFEST ]; then ++ if [ -z $A_CONFIG_FILE ]; then + echo "Error: missing config file for signing iTrustee enclave" + exit -1 + fi + +- if [ ${TA_TYPE} == 2 ]; then +- if [ -z $A_CONFIG_FILE]; then +- echo "Error: TA TYPE = 2, missing additional config file for signing iTrustee enclave" +- exit -1 +- fi +- else +- A_CONFIG_FILE="NULL" +- fi +- DEVICE_PUBKEY=${localpath}/rsa_public_key_cloud.pem +- + if [ "${CMD}"x == "sign"x ]; then + if [ -z $SIGNATURE ]; then +- DEBUG=1 +- if [ -z $SIG_KEY ] && [ ${TA_TYPE} == 2 ]; then +- echo "missing the signature private key" ++ ONE_STEP_MODE=1 ++ if [ -z $CONFIG_FILE ]; then ++ echo "Error: missing config file for signing iTrustee enclave" + exit -1 + fi +- python ${localpath}/sign_tool.py "sign" "${DEBUG}" "${IN_ENCLAVE}" "${OUT_FILE}" "${MANIFEST}" "${OTRP_FLAG}" "${TA_TYPE}" "${API_LEVEL}" "${DEVICE_PUBKEY}" "${A_CONFIG_FILE}" "${SIG_KEY}" +- else +- DEBUG=0 +- if [ -z $SERVER_PUBKEY ]; then +- echo "Error: missing server public key for verifying signature" ++ if [ -z $IN_ENCLAVE ]; then ++ echo "Error: missing enclave file" + exit -1 + fi +- python ${localpath}/sign_tool.py "sign" "${DEBUG}" "${IN_ENCLAVE}" "${OUT_FILE}" "${MANIFEST}" "${OTRP_FLAG}" "${TA_TYPE}" "${API_LEVEL}" "${DEVICE_PUBKEY}" "${A_CONFIG_FILE}" "${SIGNATURE}" "${SERVER_PUBKEY}" ++ python ${localpath}/signtool_v3.py "sign" "${ONE_STEP_MODE}" "${IN_ENCLAVE}" "${OUT_FILE}" "${CONFIG_FILE}" "${A_CONFIG_FILE}" "${API_LEVEL}" ++ else ++ ONE_STEP_MODE=0 ++ python ${localpath}/signtool_v3.py "sign" "${ONE_STEP_MODE}" "NULL" "${OUT_FILE}" "NULL" "${A_CONFIG_FILE}" "${API_LEVEL}" "${SIGNATURE}" + fi + elif [ "${CMD}"x == "digest"x ]; then +- DEBUG=0 +- python ${localpath}/sign_tool.py "digest" "${DEBUG}" "${IN_ENCLAVE}" "${OUT_FILE}" "${MANIFEST}" "${OTRP_FLAG}" "${TA_TYPE}" "${API_LEVEL}" "${DEVICE_PUBKEY}" "${A_CONFIG_FILE}" ++ ONE_STEP_MODE=0 ++ if [ -z $CONFIG_FILE ]; then ++ echo "Error: missing config file for signing iTrustee enclave" ++ exit -1 ++ fi ++ if [ -z $IN_ENCLAVE ]; then ++ echo "Error: missing enclave file" ++ exit -1 ++ fi ++ python ${localpath}/signtool_v3.py "digest" "${ONE_STEP_MODE}" "${IN_ENCLAVE}" "${OUT_FILE}" "${CONFIG_FILE}" "${A_CONFIG_FILE}" "${API_LEVEL}" + else + echo "Error: illegal command" + fi + } + + sgx_start_sign(){ ++ if [ -z $IN_ENCLAVE ]; then ++ echo "Error: missing enclave file" ++ exit -1 ++ fi + SIGDATA_FILE="signdata" + if [ "${CMD}"x == "sign"x ]; then + if [ -z $SIG_KEY ]; then +@@ -246,10 +207,6 @@ if [ -z $ENCLAVE_TYPE ]; then + echo "Error: missing enclave type" + exit -1 + fi +-if [ -z $IN_ENCLAVE ]; then +- echo "Error: missing enclave file" +- exit -1 +-fi + if [ -z $OUT_FILE ]; then + echo "Error: missing out file" + exit -1 +diff --git a/tools/sign_tool/signtool_v3.py b/tools/sign_tool/signtool_v3.py +new file mode 100644 +index 0000000..dae036f +--- /dev/null ++++ b/tools/sign_tool/signtool_v3.py +@@ -0,0 +1,428 @@ ++#!/usr/bin/env python ++# coding:utf-8 ++#---------------------------------------------------------------------------- ++# Copyright (c) Huawei Technologies Co., Ltd. 2018-2020. All rights reserved. ++# iTrustee 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: tools for generating a trusted application load image ++# Author: Li mingjuan ++# Create: 2018-02-20 ++#---------------------------------------------------------------------------- ++ ++import struct ++import os ++import sys ++import stat ++import hashlib ++import binascii ++import subprocess ++import shutil ++import getpass ++import argparse ++ ++try: ++ from configparser import SafeConfigParser ++except ImportError: ++ from ConfigParser import SafeConfigParser ++ ++from manifest import parser_manifest ++from generate_signature import gen_ta_signature ++from generate_signature import gen_hash ++ ++# fixed value, {1, 2} version are abandoned. ++VERSION = 3 ++TA_VERSION = 3 ++ ++MAX_EXT_PROP_LEN = 152 ++ ++MAGIC1 = 0xA5A55A5A ++MAGIC2 = 0x55AA ++ ++# ELF Definitions ++ELF_TYPE = 32 ++ELF_HDR_SIZE = 52 ++ELF_PHDR_SIZE = 32 ++ELF_INFO_MAGIC0_INDEX = 0 ++ELF_INFO_MAGIC1_INDEX = 1 ++ELF_INFO_MAGIC2_INDEX = 2 ++ELF_INFO_MAGIC3_INDEX = 3 ++#'\x7f' ++ELF_INFO_MAGIC0 = 127 ++#'E' ++ELF_INFO_MAGIC1 = 69 ++#'L' ++ELF_INFO_MAGIC2 = 76 ++#'F' ++ELF_INFO_MAGIC3 = 70 ++ELF_INFO_CLASS_INDEX = 4 ++ELF_INFO_CLASS_32 = 1 ++ELF_INFO_CLASS_64 = 2 ++ELF_INFO_VERSION_INDEX = 6 ++ELF_INFO_VERSION_CURRENT = 1 ++ELF_BLOCK_ALIGN = 0x1000 ++ ++ ++#---------------------------------------------------------------------------- ++# Verify ELF header contents from an input ELF file ++#---------------------------------------------------------------------------- ++def verify_elf_header(elf_path): ++ elf_type = 0 ++ with open(elf_path, 'rb') as elf: ++ elf_data = struct.unpack('B'*16, elf.read(16)) ++ elf_type = elf_data[4] ++ if ((elf_data[ELF_INFO_MAGIC0_INDEX] != ELF_INFO_MAGIC0) or \ ++ (elf_data[ELF_INFO_MAGIC1_INDEX] != ELF_INFO_MAGIC1) or \ ++ (elf_data[ELF_INFO_MAGIC2_INDEX] != ELF_INFO_MAGIC2) or \ ++ (elf_data[ELF_INFO_MAGIC3_INDEX] != ELF_INFO_MAGIC3) or \ ++ (elf_data[ELF_INFO_VERSION_INDEX] != \ ++ ELF_INFO_VERSION_CURRENT)): ++ print("invalid elf header info") ++ raise RuntimeError ++ ++ if ((elf_type == 1 and elf_data[ELF_INFO_CLASS_INDEX] != \ ++ ELF_INFO_CLASS_32) or \ ++ (elf_type == 2 and elf_data[ELF_INFO_CLASS_INDEX] != \ ++ ELF_INFO_CLASS_64) or \ ++ (elf_type != 1 and elf_type != 2)): ++ print("invliad elf format") ++ raise RuntimeError ++ return ++ ++ ++class Configuration: ++ release_type = 0 ++ otrp_flag = 0 ++ sign_type = 0 ++ public_key = "" ++ pub_key_len = 0 ++ server_ip = "" ++ config_path = "" ++ sign_key = "" ++ sign_key_len = 2048 ++ hash_type = 0 ++ padding_type = 0 ++ ++ def __init__(self, file_name): ++ parser = SafeConfigParser() ++ parser.read(file_name) ++ self.release_type = parser.get("config", "releaseType") ++ self.otrp_flag = parser.get("config", "otrpFlag") ++ self.sign_type = parser.get("config", "signType") ++ self.public_key = parser.get("config", "encryptKey") ++ self.pub_key_len = parser.get("config", "encryptKeyLen") ++ self.server_ip = parser.get("config", "serverIp") ++ self.config_path = parser.get("config", "configPath") ++ self.sign_key = parser.get("config", "signKey") ++ self.sign_key_len = parser.get("config", "signKeyLen") ++ self.hash_type = parser.get("config", "hashType") ++ self.padding_type = parser.get("config", "paddingType") ++ ++ ++def gen_header(content_len, key_version): ++ return struct.pack('IHHII', MAGIC1, MAGIC2, VERSION, content_len, \ ++ key_version) ++ ++ ++def gen_aes_key_info(cfg, iv_file_path, key_file_path, out_file_path): ++ rand_iv_cmd = "openssl rand -out {} 16".format(iv_file_path) ++ rand_key_cmd = "openssl rand -out {} 32".format(key_file_path) ++ try: ++ subprocess.check_output(rand_iv_cmd.split(), shell=False) ++ subprocess.check_output(rand_key_cmd.split(), shell=False) ++ except Exception: ++ print("rand operation failed") ++ raise RuntimeError ++ ++ os.chmod(iv_file_path, stat.S_IWUSR | stat.S_IRUSR) ++ os.chmod(key_file_path, stat.S_IWUSR | stat.S_IRUSR) ++ ++ sign_alg = 0 ++ sign_alg = sign_alg | (int(cfg.release_type) << 28) ++ sign_alg = sign_alg | (int(cfg.padding_type) << 27) ++ sign_alg = sign_alg | (int(cfg.hash_type) << 26) ++ if cfg.sign_key_len == "2048": ++ sign_alg = sign_alg | 0x00002048 ++ elif cfg.sign_key_len == "4096": ++ sign_alg = sign_alg | 0x00004096 ++ ++ print("sign_alg value is 0x%x" % sign_alg) ++ with open(out_file_path, 'wb') as out_file: ++ out_file.write(struct.pack('I', 32)) ++ out_file.write(struct.pack('I', 16)) ++ out_file.write(struct.pack('I', sign_alg)) ++ ++ with open(key_file_path, 'rb') as key_file: ++ out_file.write(key_file.read(32)) ++ ++ with open(iv_file_path, 'rb') as iv_file: ++ out_file.write(iv_file.read(16)) ++ ++ os.chmod(out_file_path, stat.S_IWUSR | stat.S_IRUSR) ++ return ++ ++ ++def encrypt_aes_key(pubkey_path, in_path, out_path): ++ cmd = "openssl rsautl -encrypt -pubin -oaep -inkey {} -in {} -out {}". \ ++ format(pubkey_path, in_path, out_path) ++ try: ++ subprocess.check_output(cmd.split(), shell=False) ++ except Exception: ++ print("RSA encrypt operation failed") ++ raise RuntimeError ++ os.chmod(out_path, stat.S_IWUSR | stat.S_IRUSR) ++ return ++ ++def gen_signature(cfg, uuid_str, raw_data_path, hash_file_path, out_file_path): ++ gen_ta_signature(cfg, uuid_str, raw_data_path, hash_file_path, out_file_path) ++ os.chmod(out_file_path, stat.S_IWUSR | stat.S_IRUSR) ++ return ++ ++def gen_raw_data(manifest_data_path, manifest_ext_path, elf_file_path, \ ++ config_path, raw_file_path): ++ manifest_size = os.path.getsize(manifest_data_path) ++ manifest_ext_size = os.path.getsize(manifest_ext_path) ++ elf_size = os.path.getsize(elf_file_path) ++ config_size = 0 ++ ++ if manifest_ext_size > MAX_EXT_PROP_LEN: ++ print("too much data in \"manifest.txt\" to be handled. \ ++ extra string len %d" \ ++ % manifest_ext_size) ++ raise RuntimeError ++ ++ verify_elf_header(elf_file_path) ++ ++ with open(raw_file_path, 'wb') as file_op: ++ header = "" ++ if os.path.isfile(config_path): ++ config_size = os.path.getsize(config_path) ++ header = struct.pack('IIIII', TA_VERSION, manifest_size, \ ++ manifest_ext_size, \ ++ elf_size, config_size) ++ file_op.write(header) ++ ++ with open(manifest_data_path, 'rb') as manifest_data: ++ file_op.write(manifest_data.read(manifest_size)) ++ ++ with open(manifest_ext_path, 'rb') as manifest_ext: ++ file_op.write(manifest_ext.read(manifest_ext_size)) ++ ++ with open(elf_file_path, 'rb') as elf: ++ file_op.write(elf.read(elf_size)) ++ if config_size != 0: ++ with open(config_path, 'rb') as config: ++ file_op.write(config.read(config_size)) ++ return ++ ++ ++def aes_encrypt(key_path, iv_path, in_file_path, out_file_path): ++ key_size = os.path.getsize(key_path) ++ with open(key_path, 'rb') as key_file: ++ key_data = key_file.read(key_size) ++ hex_key_str = binascii.b2a_hex(key_data) ++ ++ iv_size = os.path.getsize(iv_path) ++ with open(iv_path, 'rb') as iv_file: ++ iv_data = iv_file.read(iv_size) ++ hex_iv_str = binascii.b2a_hex(iv_data) ++ ++ cmd = "openssl enc -aes-256-cbc -in {} -out {} -K {} -iv {}".\ ++ format(in_file_path, out_file_path, \ ++ bytes.decode(hex_key_str), bytes.decode(hex_iv_str)) ++ try: ++ subprocess.check_output(cmd.split(), shell=False) ++ except Exception: ++ print("AES encrypt operation failed") ++ raise RuntimeError ++ ++ os.chmod(out_file_path, stat.S_IWUSR | stat.S_IRUSR) ++ return ++ ++def update_api_level(api_level, manifest): ++ data = '' ++ with open(manifest, 'r') as file_op: ++ for line in file_op: ++ if line.startswith("#") or not "gpd.ta.api_level" in line: ++ data += line ++ line = "\ngpd.ta.api_level:{}\n".format(api_level) ++ data += line ++ with open(manifest, "w") as file_op: ++ file_op.writelines(data) ++ ++ ++def update_otrp_flag(manifest): ++ data = '' ++ with open(manifest, 'r') as file_op: ++ for line in file_op: ++ if line.startswith("#") or not "gpd.ta.otrp_flag" in line: ++ data += line ++ line = "\ngpd.ta.otrp_flag:{}\n".format('true') ++ data += line ++ with open(manifest, "w") as file_op: ++ file_op.writelines(data) ++ ++ ++def gen_data_for_sign(header, key_info, raw_file, data_sign): ++ key_info_len = os.path.getsize(key_info) ++ raw_file_len = os.path.getsize(raw_file) ++ ++ with open(data_sign, 'wb') as data_fp, \ ++ open(key_info, 'rb') as key_fp, open(raw_file, 'rb') as raw_fp: ++ data_fp.write(header) ++ data_fp.write(key_fp.read(key_info_len)) ++ data_fp.write(raw_fp.read(raw_file_len)) ++ ++ ++def gen_key_version(cfg): ++ if cfg.pub_key_len == '3072': ++ return int(0x0202) ++ if cfg.pub_key_len == '2048': ++ return int(0x0002) ++ print("unhandled pulic key len %s" % cfg.pub_key_len) ++ raise RuntimeError ++ ++ ++def generate_digest(cfg, api_level, enclave_file, manifest_file, hash_path, enc_key_path, enc_raw_path): ++ # temporary files ++ in_path = os.path.dirname(os.path.abspath(manifest_file)) ++ temp_path = os.path.join(in_path, "temp") ++ shutil.rmtree(temp_path, ignore_errors=True) ++ os.mkdir(temp_path) ++ os.chmod(temp_path, stat.S_IRWXU) ++ iv_file_path = os.path.join(temp_path, "iv.bin") ++ key_file_path = os.path.join(temp_path, "aeskey.bin") ++ key_info_path = os.path.join(temp_path, "KeyInfo") ++ raw_file_path = os.path.join(temp_path, "rawData") ++ manifest_data_path = os.path.join(temp_path, "manifestData.bin") ++ manifest_ext_path = os.path.join(temp_path, "manifestExt.bin") ++ data_for_sign_path = os.path.join(temp_path, "dataForSign.bin") ++ signature_path = os.path.join(temp_path, "signature.bin") ++ ++ # mandentory input files ++ manifest_path = manifest_file ++ elf_file_path = enclave_file ++ ++ ret, product_name = parser_manifest(manifest_path, \ ++ manifest_data_path, manifest_ext_path) ++ if ret is False: ++ raise RuntimeError ++ ++ update_api_level(api_level, manifest_ext_path) ++ ++ if cfg.otrp_flag == 1: ++ print("package otrp sec file\n") ++ update_otrp_flag(manifest_ext_path) ++ ++ gen_raw_data(manifest_data_path, manifest_ext_path, elf_file_path, \ ++ cfg.config_path, raw_file_path) ++ ++ # generate AES key info to encrypt raw data ++ gen_aes_key_info(cfg, iv_file_path, key_file_path, key_info_path) ++ encrypt_aes_key(cfg.public_key, key_info_path, enc_key_path) ++ ++ aes_encrypt(key_file_path, iv_file_path, raw_file_path, enc_raw_path) ++ ++ # generate Main Header ++ content_len = os.path.getsize(enc_key_path) + \ ++ (int(cfg.sign_key_len) / 8) + \ ++ os.path.getsize(enc_raw_path) ++ key_version = gen_key_version(cfg) ++ header = gen_header(int(content_len), key_version) ++ ++ gen_data_for_sign(header, key_info_path, raw_file_path, data_for_sign_path) ++ ++ gen_hash(cfg.hash_type, data_for_sign_path, hash_path) ++ ++ #remove temp files ++ os.remove(iv_file_path) ++ os.remove(key_file_path) ++ os.remove(key_info_path) ++ os.remove(raw_file_path) ++ os.remove(manifest_data_path) ++ os.remove(manifest_ext_path) ++ os.remove(data_for_sign_path) ++ return ++ ++def gen_sec_image(cfg, enc_raw_path, enc_key_path, signature_path, out_file): ++ content_len = os.path.getsize(enc_key_path) + \ ++ (int(cfg.sign_key_len) / 8) + \ ++ os.path.getsize(enc_raw_path) ++ key_version = gen_key_version(cfg) ++ header = gen_header(int(content_len), key_version) ++ sec_img_path = out_file ++ with open(sec_img_path, 'wb') as sec_image: ++ # write to sec file [1.header info] ++ sec_image.write(header) ++ # write to sec file [2.AES key info] ++ enc_key_size = os.path.getsize(enc_key_path) ++ with open(enc_key_path, 'rb') as enc_key_info: ++ sec_image.write(enc_key_info.read(enc_key_size)) ++ # write to sec file [3.signature] ++ signature_size = os.path.getsize(signature_path) ++ with open(signature_path, 'rb') as signature_file: ++ sec_image.write(signature_file.read(signature_size)) ++ # write to sec file [4.encrypted raw data] ++ enc_raw_size = os.path.getsize(enc_raw_path) ++ with open(enc_raw_path, 'rb') as enc_raw_data: ++ sec_image.write(enc_raw_data.read(enc_raw_size)) ++ ++ print("=========================SUCCESS============================") ++ print("generate TA(V3 format) load image success: ") ++ print(sec_img_path) ++ print("============================================================") ++ ++ return ++ ++ ++def main(): ++ argvs = sys.argv ++ cmd = argvs[1] ++ one_step_mode = int(argvs[2]) ++ enclave_path = argvs[3] ++ out_file = argvs[4] ++ manifest_file = argvs[5] ++ cloud_config = argvs[6] ++ cfg = Configuration(cloud_config) ++ api_level = int(argvs[7]) ++ ++ os.umask(127) ++ ++ in_path = os.path.dirname(os.path.abspath(cloud_config)) ++ temp_path = os.path.join(in_path, "temp") ++ enc_key_path = os.path.join(temp_path, "KeyInfo.enc") ++ enc_raw_path = os.path.join(temp_path, "rawData.enc") ++ hash_path = os.path.join(temp_path, "rawDataHash.bin") ++ temp_signature = os.path.join(temp_path, "tempSignature") ++ ++ sign_tool_dir = os.path.dirname(os.path.abspath(__file__)) ++ os.chdir(sign_tool_dir) ++ if cmd == "digest": ++ generate_digest(cfg, api_level, enclave_path, manifest_file, hash_path, enc_key_path, enc_raw_path) ++ shutil.copy(hash_path, out_file) ++ elif cmd == "sign": ++ if one_step_mode == 0: ++ in_signature = argvs[8] ++ gen_sec_image(cfg, enc_raw_path, enc_key_path, in_signature, out_file) ++ else: ++ generate_digest(cfg, api_level, enclave_path, manifest_file, hash_path, enc_key_path, enc_raw_path) ++ gen_ta_signature(cfg, hash_path, temp_signature) ++ in_signature = temp_signature ++ gen_sec_image(cfg, enc_raw_path, enc_key_path, in_signature, out_file) ++ os.remove(temp_signature) ++ os.remove(enc_key_path) ++ os.remove(enc_raw_path) ++ os.remove(hash_path) ++ #remove temp files ++ shutil.rmtree(temp_path) ++ ++ ++if __name__ == '__main__': ++ main() ++ +-- +2.27.0 + diff --git a/secGear.spec b/secGear.spec index 60703ea5771462f095597c167b3a2527aa8ccd50..794b8c282efe175d6556210b739eb90148f4a0d8 100644 --- a/secGear.spec +++ b/secGear.spec @@ -1,6 +1,6 @@ Name: secGear Version: 0.1.0 -Release: 13%{?dist} +Release: 14%{?dist} Summary: secGear is an SDK to develop confidential computing apps based on hardware enclave features ExclusiveArch: x86_64 @@ -26,6 +26,7 @@ Patch13: 0014-set-umask-in-sign_tool.sh.patch Patch14: 0015-1.fix-the-race-of-ecall-and-enclave-destroy.patch Patch15: 0016-fix-wrong-spelling-and-null-pointer-dereference-issu.patch Patch16: 0017-update-signtool-codegen.patch +Patch17: 0018-some-adaptations-for-trustzone.patch BuildRequires: gcc python3 automake autoconf libtool BUildRequires: glibc glibc-devel cmake ocaml-dune @@ -124,6 +125,9 @@ popd %endif %changelog +* Tue May 18 2021 zhangguangzhi3 - 0.1.0-14 +- DESC: some adaptations for trustzone + * Wed May 12 2021 yanlu - 0.1.0-13 - DESC: update signtool and codegen