From 45cf3b4bb86d5dc9d149f5e6056e9b2cb27eff63 Mon Sep 17 00:00:00 2001
From: zgzxx <zhangguangzhi3@huawei.com>
Date: Tue, 18 May 2021 14:27:31 +0800
Subject: [PATCH 12/14] some adaptations for trustzone

---
 CMakeLists.txt                                |  11 +-
 README.en.md                                  |   2 +-
 README.md                                     |   2 +-
 docs/sign_tool.md                             |  19 +-
 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 ++++++++++++++++
 27 files changed, 802 insertions(+), 716 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 3886316..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/README.en.md b/README.en.md
index aa8c4a8..8aaa1b0 100644
--- a/README.en.md
+++ b/README.en.md
@@ -335,7 +335,7 @@ so -nostdinc -nodefaultlibs -nostdlib -nodefaultlibs compile link options was in
 
 		add_custom_command(TARGET ${PREFIX}
 			POST_BUILD
-			COMMAND bash ${SIGN_TOOL} -d sign -x trustzone -i lib${PREFIX}.so -c ${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt
+			COMMAND bash ${SIGN_TOOL} -d sign -x trustzone -i lib${PREFIX}.so -c ${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt -m ${CMAKE_CURRENT_SOURCE_DIR}/config_cloud.ini
 			-o ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT})
 
 		install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT}
diff --git a/README.md b/README.md
index a90450b..b95dcc9 100644
--- a/README.md
+++ b/README.md
@@ -315,7 +315,7 @@ AUTO_FILES：由edl文件生成的安全侧二进制文件
 
 		add_custom_command(TARGET ${PREFIX}
 			POST_BUILD
-			COMMAND bash ${SIGN_TOOL} -d sign -x trustzone -i lib${PREFIX}.so -c ${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt
+			COMMAND bash ${SIGN_TOOL} -d sign -x trustzone -i lib${PREFIX}.so -c ${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt -m ${CMAKE_CURRENT_SOURCE_DIR}/config_cloud.ini
 			-o ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT})
 
 		install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT}
diff --git a/docs/sign_tool.md b/docs/sign_tool.md
index ccaa2e6..399e4c5 100644
--- a/docs/sign_tool.md
+++ b/docs/sign_tool.md
@@ -13,38 +13,37 @@ The tool supports the following two modes:
 
     For example:    
 
-    `$ ./sign_tool.sh –d sign –x trustzone –i test.enclave -c manifest.txt –o signed.enclave `
+    `$ ./sign_tool.sh –d sign –x trustzone –i test.enclave -c manifest.txt -m config_cloud.ini –o signed.enclave `
 
 
 - two-step method, it is used when the signature needs to be obtained from the signing organization or the private key is stored on another secure platform.  
 
     For example:  
     (1) generate the digest value.  
-    `$ ./sign_tool.sh –d digest –x trustzone –i input -c manifest.txt –o digest.data `
+    `$ ./sign_tool.sh –d digest –x trustzone –i input -c manifest.txt -m config_cloud.ini –o digest.data `
 
     For trustzone, temporary files KeyInfo.enc, rawData.enc, and rawDataHash.bin are generated in the current directory. And for sgx, a temporary file signdata is generated in the current directory. The temporary file is required when generating the signed enclave in step 3 and is deleted after the signed enclave is generated.  
 
     (2) send the digest.data to the signing organization or platform and get the signature.  
 
     (3) use the signature to generate the signed enclave.  
-    `$ ./sign_tool.sh –d sign –x trustzone –i input -c manifest.txt –p pub.pem –s signature –o signed.enclave `
+    `$ ./sign_tool.sh –d sign –x trustzone –i input -c manifest.txt -m config_cloud.ini –s signature –o signed.enclave `
 
 ## sign_tool.sh parameter
 
 ```
-    -a <parameter>  API_LEVEL, indicates trustzone GP API version, defalut is 1.
     -c <file>       basic config file.
     -d <parameter>  sign tool command, sign/digest.
                     The sign command is used to generate a signed enclave.
                     The digest command is used to generate a digest value.
-    -f <parameter>  OTRP_FLAG, indicates whether the OTRP standard protocol is supported, default is 0.
     -i <file>       enclave to be signed.
-    -k <file>       private key required for single-step method, required when trustzone TA_TYPE is 2 or sgx.
-    -m <file>       additional config for trustzone when TA_TYPE is 2.
-    -o <file>       output parameters, the sign command outputs sigend enclave, the digest command outputs digest value.
+    -k <file>       private key required for single-step method
+    -m <file>       additional config_cloud.ini for trustzone.
+    -o <file>       output parameters, the sign command outputs sigend enclave, the digest command outputs
+                    digest value.
     -p <file>       signing server public key certificate, required for two-step method.
-    -s <file>       the signed digest value required for two-step method, this parameter is empty to indicate single-step method.
-    -t <parameter>  trustzone TA_TYPE, default is 1.
+    -s <file>       the signed digest value required for two-step method, this parameter is empty to indicate
+                    single-step method.
     -x <parameter>  enclave type, sgx or trustzone.
     -h              printf help message.
 ```
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
new file mode 100644
index 0000000..cfd0171
--- /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 cp ${LOCAL_ROOT_PATH}/inc/host_inc/sgx/*.h ${CMAKE_BINARY_DIR}/inc/secGear/
+		COMMAND cp ${LOCAL_ROOT_PATH}/inc/host_inc/sgx/*.edl ${CMAKE_BINARY_DIR}/inc/secGear/
+		COMMAND 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..d78354e
--- /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 <linux/limits.h>
 #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 <parameter>  API_LEVEL, indicates trustzone GP API version, defalut is 1."
     echo "-c <file>       basic config file."
     echo "-d <parameter>  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 <parameter>  OTRP_FLAG, indicates whether the OTRP standard protocol is supported, default is 0."
     echo "-i <file>       enclave to be signed."
-    echo "-k <file>       private key required for single-step method, required when trustzone TA_TYPE is 2 or sgx."
-    echo "-m <file>       additional config for trustzone when TA_TYPE is 2."
+    echo "-k <file>       private key required for single-step method"
+    echo "-m <file>       additional config_cloud.ini for trustzone."
     echo "-o <file>       output parameters, the sign command outputs sigend enclave, the digest command outputs"
     echo "                digest value."
     echo "-p <file>       signing server public key certificate, required for two-step method."
     echo "-s <file>       the signed digest value required for two-step method, this parameter is empty to indicate"
     echo "                single-step method."
-    echo "-t <parameter>  trustzone TA_TYPE, default is 1."
     echo "-x <parameter>  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

