From e1747bb214b01afc538d3d2c3b5fd3554bae015a Mon Sep 17 00:00:00 2001 From: "zhangzhenyu (M)" Date: Wed, 28 Jun 2023 15:15:59 +0800 Subject: [PATCH] update 7.3.0 release cloud sdk --- README | 2 +- build/pack-App/Readme.txt | 7 + build/pack-App/pack.py | 178 +++++++ build/pack-App/pack_tools/configs_mask.xml | 15 + build/pack-App/pack_tools/manifest_mask.txt | 8 + build/pack-Config/Config_pre.py | 11 +- build/signtools/auth_conf_parser.py | 68 +-- build/signtools/config_cloud_app.ini | 60 +++ build/signtools/config_tee_private_sample.ini | 3 +- build/signtools/dyn_conf_checker.py | 34 +- build/signtools/dyn_conf_parser.py | 23 +- build/signtools/generate_signature.py | 2 +- build/signtools/get_ta_elf_hash.py | 67 ++- build/signtools/manifest.py | 19 + build/signtools/signtool_v3.py | 440 +++++++++++------- build/signtools/tag_parse_dict.csv | 6 + include/CA/tee_client_api.h | 4 - .../TA/huawei_ext/crypto_device_key_wrapper.h | 31 -- include/TA/huawei_ext/crypto_ec_wrapper.h | 4 +- .../TA/huawei_ext/crypto_ec_x509_wrapper.h | 2 +- include/TA/huawei_ext/crypto_inner_wrapper.h | 4 +- include/TA/huawei_ext/crypto_x509_wrapper.h | 22 +- include/TA/huawei_ext/permsrv_api_legacy.h | 1 + include/TA/huawei_ext/tee_ext_api.h | 25 +- include/TA/huawei_ext/tee_hw_ext_api_legacy.h | 73 --- include/TA/huawei_ext/tee_log.h | 24 +- include/TA/tee_arith_api.h | 4 +- include/TA/tee_crypto_api.h | 36 +- include/TA/tee_defines.h | 15 +- include/TA/tee_object_api.h | 8 +- include/TA/tee_property_api.h | 2 - include/TA/tee_trusted_storage_api.h | 14 +- test/TA/helloworld/Makefile | 2 +- thirdparty/open_source/musl/libc/hm/thread.h | 2 +- .../open_source/musl/libc/sys/scs_security.h | 11 + .../open_source/musl/libc/sys/sysinfo.h | 38 ++ tools/ca_auth_hash_tools/ReadMe.txt | 23 + tools/ca_auth_hash_tools/ca_caller_info.xml | 15 + .../ca_auth_hash_tools/calc_ca_caller_hash.py | 227 +++++++++ 39 files changed, 1130 insertions(+), 400 deletions(-) create mode 100644 build/pack-App/Readme.txt create mode 100644 build/pack-App/pack.py create mode 100644 build/pack-App/pack_tools/configs_mask.xml create mode 100644 build/pack-App/pack_tools/manifest_mask.txt create mode 100644 build/signtools/config_cloud_app.ini delete mode 100644 include/TA/huawei_ext/crypto_device_key_wrapper.h create mode 100644 thirdparty/open_source/musl/libc/sys/scs_security.h create mode 100644 thirdparty/open_source/musl/libc/sys/sysinfo.h create mode 100644 tools/ca_auth_hash_tools/ReadMe.txt create mode 100644 tools/ca_auth_hash_tools/ca_caller_info.xml create mode 100644 tools/ca_auth_hash_tools/calc_ca_caller_hash.py diff --git a/README b/README index 6811e56..a6d8a5c 100644 --- a/README +++ b/README @@ -13,7 +13,7 @@ $ cd test/CA/helloworld $ make $ cd test/TA/helloworld $ make -copy build result CA executable file and TA binary(xxx.sec) to /vendor/bin/ +copy build result CA executable file and TA binary(xxx.sec) to /var/itrustee/ta #the path "/vendor/bin/" may be changed as your opinion, make sure it consistent with the path defined in your TA's source code $ /vendor/bin/demo_hello diff --git a/build/pack-App/Readme.txt b/build/pack-App/Readme.txt new file mode 100644 index 0000000..dc94ad6 --- /dev/null +++ b/build/pack-App/Readme.txt @@ -0,0 +1,7 @@ +Instructions for use +1. Create a file in the current directory and name it, for example: "opencv". +2. Place the python/java program to be executed in the opencv directory. +3. Generate the RSA4096 public-private key pair (for signature verification), + send the public key to the TA certificate issued by the server administrator, + and save the TA certificate and private key to the package-tools directory in the current folder. +4. Run the compilation script pack.py to obtain the sec file, for example: "python3 pack.py opencv". diff --git a/build/pack-App/pack.py b/build/pack-App/pack.py new file mode 100644 index 0000000..991fed8 --- /dev/null +++ b/build/pack-App/pack.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python3 +# coding=utf-8 +#---------------------------------------------------------------------------- +# Copyright @ Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. +# Licensed under the Mulan PSL v2. +# You can use this software according to the terms and conditions of the Mulan +# PSL v2. +# You may obtain a copy of Mulan PSL v2 at: +# http://license.coscl.org.cn/MulanPSL2 +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +# KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +# NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +# See the Mulan PSL v2 for more details. +# Description: pack python or java files to sec +#---------------------------------------------------------------------------- + +''' tools for packing apps ''' + +from __future__ import absolute_import +import sys +import os +import re +import zlib +import struct +import logging +import subprocess +sys.path.append('../pack-Config') +from Config_pre import gen_data_for_sign + + +COMPRESS_LEVEL = 9 +MAGIC1 = 0xA5A55A5A +MAGIC2 = 0x55AA + + +def add_head_to_tgz(infile, infile_size, tgz_version): + """ add head to tgz """ + raw_tag = 'IHHI256s' + with os.fdopen(os.open("libcombine.so", os.O_RDWR | os.O_CREAT, 0o755), \ + "wb", 0o755) as combine_fd: + with os.fdopen(os.open(infile, os.O_RDWR | os.O_CREAT, 0o755), \ + "rb", 0o755) as tgz_fd: + tgz_str = tgz_fd.read() + reserved_seg = "" + header = struct.pack(raw_tag, MAGIC1, MAGIC2, tgz_version, \ + infile_size, bytes(reserved_seg.encode('utf-8'))) + combine_fd.write(header) + combine_fd.write(tgz_str) + + +def compress(infile, dst, level): + """ do compress """ + with os.fdopen(os.open(dst, os.O_RDWR | os.O_CREAT, 0o755), \ + "wb", 0o755) as out_file_fd: + with open(infile, "rb", 0o755) as file_op: + compress_fd = zlib.compressobj(level) + data = file_op.read(1024) + while data: + out_file_fd.write(compress_fd.compress(data)) + data = file_op.read(1024) + out_file_fd.write(compress_fd.flush()) + + +def run_cmd(command): + """ run shell cmd """ + ret = subprocess.run(command, shell=False, check=True) + if ret.returncode != 0: + logging.error("run command failed.") + sys.exit(1) + + +def run_clean(): + """ delete build files """ + cmd = ["rm", "libcombine.so", "config", "manifest.txt", "configs.xml"] + run_cmd(cmd) + logging.critical("success to clean") + + +def get_file_type(file_name): + """ get the user file type """ + for root, dirs, files in os.walk(file_name): + file_name_list = str(files) + if ".py" in file_name_list: + file_type_num = "6" # means python + return file_type_num + if ("java" in file_name_list) or (".class" in file_name_list): + file_type_num = "7" # means java + return file_type_num + logging.info("warning : the input file type cannot be distinguished. \ + need python or java") + logging.info("warning: the default value is python") + file_type_num = "6" # default python + return file_type_num + + +def replace_file_content(input_file, out_file, pkg_name, pkg_type_num): + """ replace the specified content of the file """ + with os.fdopen(os.open(out_file, os.O_RDWR | os.O_CREAT, 0o755), \ + "w", 0o755) as out_file_fd: + with os.fdopen(os.open(input_file, os.O_RDWR | os.O_CREAT, 0o755), \ + "r", 0o755) as file_op: + content_str = file_op.read() + content_str = content_str.replace("APP_TYPE", str(pkg_type_num)) + content_str = content_str.replace("APP_NAME", pkg_name) + out_file_fd.write(content_str) + + +def whitelist_check(intput_str): + """ whitelist check """ + if not re.match(r"^[A-Za-z0-9\/\-_.]+$", intput_str): + return 1 + return 0 + + +def main(): + """ main process """ + if len(sys.argv) < 2: + logging.error("pack.py need input folders") + sys.exit(1) + file_name = sys.argv[1] + work_path = os.getcwd() + output_path = work_path + if whitelist_check(file_name): + logging.error("file name is incorrect") + sys.exit(1) + tar_file_name = "{}.tar".format(file_name) + tgz_file_name = "{}.tar.gz".format(file_name) + ta_cert_file_path = "pack_tools/ta_cert.der" + signtool_path = "{}/../signtools/signtool_v3.py".format(work_path) + ini_file_path = "{}/../signtools/config_cloud_app.ini".format(work_path) + + # 0. clean by user and check input + if file_name == "clean": + run_clean() + sys.exit(0) + elif os.path.exists(file_name): + logging.critical("start pack %s", file_name) + else: + logging.error("%s is not exist, please check", file_name) + sys.exit(1) + + # 1. get file type + file_type_num = get_file_type(file_name) + + # 2. make package + cmd = ["tar", "cvf", tar_file_name, file_name] + run_cmd(cmd) + tar_file_size = os.path.getsize(tar_file_name) + + # 3. make tgz file + compress(tar_file_name, tgz_file_name, COMPRESS_LEVEL) + + # 4. change tgz file to libcombine.so and add head + tgz_version = 1 + add_head_to_tgz(tgz_file_name, tar_file_size, tgz_version) + + # 5. replace file name type content + replace_file_content("pack_tools/manifest_mask.txt", "manifest.txt", \ + file_name, file_type_num) + replace_file_content("pack_tools/configs_mask.xml", "configs.xml", \ + file_name, file_type_num) + + # 6. build config + config_path = "{}/config".format(work_path) # this parameter is not required but must exist. + gen_data_for_sign(work_path, ta_cert_file_path, config_path) + cmd = ["mv", "data_for_sign", "config"] + run_cmd(cmd) + + # 7. do sign process + cmd = ["python3", "-B", signtool_path, work_path, output_path, "--privateCfg", ini_file_path] + run_cmd(cmd) + + # 8. do clean + run_clean() + logging.critical("success to packing %s", file_name) + +if __name__ == '__main__': + main() diff --git a/build/pack-App/pack_tools/configs_mask.xml b/build/pack-App/pack_tools/configs_mask.xml new file mode 100644 index 0000000..ccf7da6 --- /dev/null +++ b/build/pack-App/pack_tools/configs_mask.xml @@ -0,0 +1,15 @@ + + + +APP_NAME +00000000-0000-0000-0000-000000000000 + + +false +8192 +81920 +false +true +6 + + diff --git a/build/pack-App/pack_tools/manifest_mask.txt b/build/pack-App/pack_tools/manifest_mask.txt new file mode 100644 index 0000000..d2f57b4 --- /dev/null +++ b/build/pack-App/pack_tools/manifest_mask.txt @@ -0,0 +1,8 @@ +gpd.ta.appID: 00000000-0000-0000-0000-000000000000 +gpd.ta.service_name: APP_NAME +gpd.ta.singleInstance: true +gpd.ta.multiSession: false +gpd.ta.instanceKeepAlive: false +gpd.ta.dataSize: 81920 +gpd.ta.stackSize: 8192 +gpd.ta.target_type: APP_TYPE diff --git a/build/pack-Config/Config_pre.py b/build/pack-Config/Config_pre.py index 39f3309..c305bf7 100644 --- a/build/pack-Config/Config_pre.py +++ b/build/pack-Config/Config_pre.py @@ -58,11 +58,16 @@ class load_config_header: str = struct.Struct('IHHIIIIIIIII') def __init__(self, data): - unpacked_data = (load_config_header.str).unpack(data.encode()) + if isinstance(data, bytes): + unpacked_data = (load_config_header.str).unpack(data) + elif isinstance(data, str): + unpacked_data = (load_config_header.str).unpack(data.encode()) + else: + logging.error("wrong input unpacked_data type") self.unpacked_data = unpacked_data self.magic_num = unpacked_data[0] self.version = unpacked_data[1] - self.policy_versio = unpacked_data[2] + self.policy_version = unpacked_data[2] self.context_len = unpacked_data[3] self.ta_cert_len = unpacked_data[4] self.config_len = unpacked_data[5] @@ -161,7 +166,7 @@ def delete_temp_folder(input_path_delete): def convert_xml2tlv(xml_file, tlv_file, input_path): ''' configs.xml exchange to tlv ''' if (get_policy_version() & (1 << XML2TLV_PARSE_TOOL_INDEX)) == XML2TLV_PY_VALUE: - csv_dir = os.path.realpath(os.path.join(os.getcwd(), 'xml2tlv_tools/csv')) + csv_dir = os.path.realpath(os.path.join(os.getcwd(), '../signtools')) tag_parse_dict_file_path = \ os.path.join(csv_dir, 'tag_parse_dict.csv') parser_config_xml(xml_file, tag_parse_dict_file_path, \ diff --git a/build/signtools/auth_conf_parser.py b/build/signtools/auth_conf_parser.py index cf525b1..3dc586c 100644 --- a/build/signtools/auth_conf_parser.py +++ b/build/signtools/auth_conf_parser.py @@ -41,11 +41,11 @@ DEFAULT_AUTH_TYPE_UID = True # init caller info -g_caller_num = 0 -g_caller_enable = 1 -g_hash_byte_list = bytes("", 'utf-8') -g_auth_type = True # default auth type: cmdline + uid -g_big_endian = False +CALLER_NUM = 0 +CALLER_ENABLE = 1 +HASH_BYTE_LIST = bytes("", 'utf-8') +AUTH_TYPE = True # default auth type: cmdline + uid +SIGN_BIG_ENDIAN = False def print_hash(byte_buf): @@ -85,11 +85,11 @@ def check_auth_enable_type(value): def get_auth_enable_value(value): """ check auth_enable value """ - global g_caller_enable + global CALLER_ENABLE if value == "false": - g_caller_enable = 0 + CALLER_ENABLE = 0 else: - g_caller_enable = 1 + CALLER_ENABLE = 1 def check_auth_type(value): @@ -102,11 +102,11 @@ def check_auth_type(value): def get_auth_type_value(value): """ check auth type value """ - global g_auth_type + global AUTH_TYPE if value == "false": - g_auth_type = False + AUTH_TYPE = False else: - g_auth_type = True + AUTH_TYPE = True def check_item_type(item): @@ -140,9 +140,9 @@ def get_item_value(item, auth_type): cmdline = "" uid = 0 username = "" - caller_hash = "" - global g_caller_num - global g_hash_byte_list + caller_hash = bytes() + global CALLER_NUM + global HASH_BYTE_LIST if auth_type == DEFAULT_AUTH_TYPE_UID: attr_key = "uid" @@ -171,13 +171,13 @@ def get_item_value(item, auth_type): caller_hash = calc_cmdline_username_hash(cmdline, username) logging.info("cmdline %s, username %s", cmdline, username) print_hash(caller_hash) - if g_big_endian is True: + if SIGN_BIG_ENDIAN is True: pack_format = ">32s" else: pack_format = "32s" - g_hash_byte_list = g_hash_byte_list + struct.pack(pack_format, caller_hash) - g_caller_num = g_caller_num + 1 - if g_caller_num > MAX_CALLER_NUM: + HASH_BYTE_LIST = HASH_BYTE_LIST + struct.pack(pack_format, caller_hash) + CALLER_NUM = CALLER_NUM + 1 + if CALLER_NUM > MAX_CALLER_NUM: raise RuntimeError("Exceed max caller num", MAX_CALLER_NUM) @@ -210,10 +210,10 @@ def do_parser_auth_conf(root): if xml_line_num != 0: raise RuntimeError("the auth_base_info must be configured first") handle_auth_base_info(child) - if g_auth_type != DEFAULT_AUTH_TYPE_UID: + if AUTH_TYPE != DEFAULT_AUTH_TYPE_UID: auth_tag = "auth_cmdline_username" elif child.tag == auth_tag: - handle_auth_item(child, g_auth_type) + handle_auth_item(child, AUTH_TYPE) else: raise RuntimeError("not support xml tag", child.tag) xml_line_num = xml_line_num + 1 @@ -221,11 +221,17 @@ def do_parser_auth_conf(root): def parser_auth_xml(auth_xml_file_path, manifest_ext_path, big_endian=False): """ parser auth xml """ - global g_caller_num - global g_hash_byte_list - global g_big_endian - - g_big_endian = big_endian + global CALLER_NUM + global CALLER_ENABLE + global HASH_BYTE_LIST + global AUTH_TYPE + global SIGN_BIG_ENDIAN + + CALLER_NUM = 0 + CALLER_ENABLE = 1 + HASH_BYTE_LIST = bytes("", 'utf-8') + AUTH_TYPE = True + SIGN_BIG_ENDIAN = big_endian if not os.path.exists(auth_xml_file_path): raise RuntimeError("auth_config.xml file doesn't exist") @@ -237,15 +243,15 @@ def parser_auth_xml(auth_xml_file_path, manifest_ext_path, big_endian=False): do_parser_auth_conf(root) # gen auth header - if g_caller_enable == 0: - g_caller_num = 0 - g_hash_byte_list = bytes("", 'utf-8') + if CALLER_ENABLE == 0: + CALLER_NUM = 0 + HASH_BYTE_LIST = bytes("", 'utf-8') - if g_big_endian is True: + if SIGN_BIG_ENDIAN is True: pack_format = ">II" else: pack_format = "II" - auth_header = struct.pack(pack_format, g_caller_enable, g_caller_num) + auth_header = struct.pack(pack_format, CALLER_ENABLE, CALLER_NUM) #write auth to mani_ext if not os.path.exists(manifest_ext_path): @@ -255,6 +261,6 @@ def parser_auth_xml(auth_xml_file_path, manifest_ext_path, big_endian=False): with os.fdopen(fd_ext, 'ba+') as fp_mani_ext: fp_mani_ext.write(bytes(AUTH_CONFIG_KEY, "utf-8")) fp_mani_ext.write(auth_header) - fp_mani_ext.write(g_hash_byte_list) + fp_mani_ext.write(HASH_BYTE_LIST) fp_mani_ext.write(bytes("\n", "utf-8")) fp_mani_ext.close() diff --git a/build/signtools/config_cloud_app.ini b/build/signtools/config_cloud_app.ini new file mode 100644 index 0000000..65fa865 --- /dev/null +++ b/build/signtools/config_cloud_app.ini @@ -0,0 +1,60 @@ +[signSecPrivateCfg] +;;; +;private key length for signing TA: +;[fixed value] +;256 ECDSA Alg +;2048/4096 RSA Alg +secSignKeyLen = 4096 +;;; +;[fixed value] +;0 means SHA256 hash type +;1 means SHA512 hash type +secHashType = 0 +;;; +; [fixed value] +;0 means padding type is pkcs1v15 +;1 means padding type is PSS +;[fixed value] +secPaddingType = 1 +;;; +;[fixed value] +;RSA alg +;ECDSA alg +;SM2 alg +secSignAlg = RSA +;;; +;public key for encrypt TA +secEncryptKey = rsa_public_key_cloud.pem +;;; +;public key length +secEncryptKeyLen = 3072 + +[signSecPublicCfg] +;;; +;[fixed value] +; sec sign key type +;0 means debug +;1 means release +secReleaseType = 1 +;;; +;0 means TA not installed by OTRP +;1 means TA installed by OTRP +secOtrpFlag = 0 +;;; +;0 means not sign +;1 means signed by local private +;2 means signed using native sign tool; +;3 means signed by CI +;[fixed value] +secSignType = 1 +;;; +;server address for signing TA +secSignServerIp = +;;; +;private key for signing TA +;[private key owned by yourself] +secSignKey = ../pack-App/pack_tools/private_key.pem +;;; +;config file +;[signed config file by Huawei] +configPath = ../pack-App/config diff --git a/build/signtools/config_tee_private_sample.ini b/build/signtools/config_tee_private_sample.ini index 5b2bb9c..bf5bc84 100644 --- a/build/signtools/config_tee_private_sample.ini +++ b/build/signtools/config_tee_private_sample.ini @@ -20,7 +20,8 @@ secSignAlg = RSA ;0 config证书 configVersion = 0 ;;; -; Fixed value 1 +;0 is openharmony +;1 is not openharmony configPolicy = 1 ;;; ;RSA_PKCS1 alg diff --git a/build/signtools/dyn_conf_checker.py b/build/signtools/dyn_conf_checker.py index 64eeaf2..0b37bce 100644 --- a/build/signtools/dyn_conf_checker.py +++ b/build/signtools/dyn_conf_checker.py @@ -22,10 +22,16 @@ uuid_split_sym_list = ['-'] spilt_sym_list = [';', '|', ','] unused_sym_list = ['_'] unique_list = [] +map_region_sym_list = ['-', '_', ':', '.', '@', ";"] permission_unique_dict = {} cmd_unique_dict = {} +def dyn_conf_clean(): + ''' dyn conf clean ''' + unique_list.clear() + + def check_csv_sym(value): for sym in value: @@ -59,18 +65,19 @@ def check_context_sym(old_item, attr, value): for sym in value: if sym in uuid_split_sym_list: continue - elif sym in spilt_sym_list: + if sym in spilt_sym_list: continue - elif sym in unused_sym_list: + if sym in unused_sym_list: continue - elif sym >= 'A' and sym <= 'Z': + if sym in map_region_sym_list: continue - elif sym >= 'a' and sym <= 'z': + if 'A' <= sym <= 'Z': continue - elif sym >= '0' and sym <= '9': + if 'a' <= sym <= 'z': continue - else: - raise RuntimeError("has invalid sym in xml", \ + if '0' <= sym <= '9': + continue + raise RuntimeError("has invalid sym in xml", \ old_item + attr, value) return 0 @@ -165,6 +172,13 @@ def check_virt2phys(value): raise RuntimeError("virt2phys must be true or false", value) +def check_get_vsrootinfo(value): + ''' check get vsrootinfo ''' + if len(value) > 0: + if value.lower() != 'true' and value.lower() != 'false': + raise RuntimeError("get_vsrootinfo must be true or false", value) + + def check_exception_mode(value): if value != "restart" and value != "syscrash" and value != "ddos": @@ -341,7 +355,7 @@ def check_permssion_unique(value, origin_value): RuntimeError("permssion trans by csv failed", value, origin_value) for (i, _) in enumerate(value_list): - if value_list[i] in permission_unique_dict.keys() and \ + if value_list[i] in iter(permission_unique_dict) and \ permission_unique_dict.get(value_list[i]) != origin_value_list[i]: raise RuntimeError("different permission set same num in csv",\ value, origin_value) @@ -356,7 +370,7 @@ def check_cmd_unique(value, origin_value): RuntimeError("cmd trans by csv failed", value, origin_value) for (i, _) in enumerate(value_list): - if value_list[i] in cmd_unique_dict.keys() and \ + if value_list[i] in iter(cmd_unique_dict) and \ cmd_unique_dict.get(value_list[i]) != origin_value_list[i]: raise RuntimeError("different cmd set same num in csv", \ value, origin_value) @@ -426,6 +440,8 @@ def dyn_perm_check(dyn_key, attrib, value, origin_value): check_upgrade(value) elif dyn_key == 'drv_perm/drv_basic_info/virt2phys': check_virt2phys(value) + elif dyn_key == 'drv_perm/drv_basic_info/get_vsrootinfo': + check_get_vsrootinfo(value) elif dyn_key == 'drv_perm/drv_basic_info/exception_mode': check_exception_mode(value) elif dyn_key == 'drv_perm/drv_io_map/item/chip_type': diff --git a/build/signtools/dyn_conf_parser.py b/build/signtools/dyn_conf_parser.py index 7ecb7f6..9e1302f 100644 --- a/build/signtools/dyn_conf_parser.py +++ b/build/signtools/dyn_conf_parser.py @@ -23,6 +23,7 @@ from dyn_conf_checker import dyn_perm_check from dyn_conf_checker import check_and_classify_attr from dyn_conf_checker import check_csv_sym from dyn_conf_checker import check_ta_config +from dyn_conf_checker import dyn_conf_clean type_trans = {"TYPE_NONE": "-1", @@ -34,6 +35,9 @@ type_trans = {"TYPE_NONE": "-1", # the length len in tlv DYN_CONF_LEN_LEN = 4 +# the map_regions num +MAP_REGIONS_NUM = 0 + tag_dict = {} type_dict = {} trans_dict = {} @@ -218,8 +222,15 @@ def get_length(value): return ans -def do_parser_dyn_conf(old_item, ele, in_path): +def check_map_regions(length): + ''' check the regions strion length ''' + if int(length, 16) > 1279: + logging.error("regions string is too long\n") + raise RuntimeError("regions has invalid length", int(length, 16)) + +def do_parser_dyn_conf(old_item, ele, in_path): + ''' parse dyn config to tlv ''' attrs = "" if len(ele.attrib) > 0: for attr in ele.attrib: @@ -234,6 +245,11 @@ def do_parser_dyn_conf(old_item, ele, in_path): ele.attrib, in_path) length = get_length(value) attrs = attrs + tag + dyn_type + length + value + if tag == "037" and dyn_type == "3": + check_map_regions(length) + # the map_regions num + global MAP_REGIONS_NUM + MAP_REGIONS_NUM += 1 else: for child in ele: tmp_attrs = do_parser_dyn_conf(old_item + child.tag + "/", @@ -273,6 +289,10 @@ def parser_dyn_conf(dyn_conf_xml_file_path, manifest_ext_path, root = tree.getroot() ans = do_parser_dyn_conf(root.tag + "/", root, in_path) + dyn_conf_clean() + if MAP_REGIONS_NUM > 1: + raise RuntimeError("regions has invalid num", MAP_REGIONS_NUM) + if ans == "": ans = "00000" @@ -306,6 +326,7 @@ def parser_config_xml(config_xml_file_path, tag_parse_dict_path, \ root = tree.getroot() ans = do_parser_dyn_conf(root.tag + "/", root, in_path) + dyn_conf_clean() if ans == "": ans = "00000" diff --git a/build/signtools/generate_signature.py b/build/signtools/generate_signature.py index 95657e8..8e55f5a 100644 --- a/build/signtools/generate_signature.py +++ b/build/signtools/generate_signature.py @@ -23,7 +23,7 @@ from generate_hash import gen_hash def gen_ta_signature(cfg, uuid_str, raw_data, raw_data_path, hash_file_path, \ - out_file_path, out_path, key_info_data, is_big_ending): + out_file_path, out_path, key_info_data, is_big_ending, temp_path): msg_file = os.path.join(out_path, "temp", "config_msg") fd_msg = os.open(msg_file, os.O_WRONLY | os.O_CREAT, \ stat.S_IWUSR | stat.S_IRUSR) diff --git a/build/signtools/get_ta_elf_hash.py b/build/signtools/get_ta_elf_hash.py index 89443e0..59034d4 100644 --- a/build/signtools/get_ta_elf_hash.py +++ b/build/signtools/get_ta_elf_hash.py @@ -24,6 +24,15 @@ import sys import hashlib import struct import logging +import re +from base64 import urlsafe_b64encode + + +def whitelist_check(intput_str): + """ check str """ + if not re.match(r"^[A-Za-z0-9\/\-_.]+$", intput_str): + return 1 + return 0 def elf_header_verify_check(elf_header): @@ -179,8 +188,13 @@ class ElfInfo: self.exec_flag = 0x1 -def get_code_segment_from_elf(elf_file_name, out_hash_file_name, sign_data): - """ verify ELF header information """ +def base64url_encode(data): + """ encode data with base64Url """ + return urlsafe_b64encode(data).rstrip(b'=') + + +def calculate_mem_hash(elf_file_name): + """ calculate mem hash summary """ hash_value_summary = "" elf_info = ElfInfo() @@ -209,7 +223,6 @@ def get_code_segment_from_elf(elf_file_name, out_hash_file_name, sign_data): logging.error("No Support ELFINFO_CLASS") if (elf_phd_header.p_type != elf_info.load_type) or \ - (elf_phd_header.p_flags & elf_info.exec_flag != elf_info.exec_flag) or \ (elf_phd_header.p_flags & elf_info.write_flag == elf_info.write_flag): continue @@ -222,7 +235,7 @@ def get_code_segment_from_elf(elf_file_name, out_hash_file_name, sign_data): alignment_len = (len(elf_segment_buf) // 4096 + 1) * 4096 elf_segment_buf = elf_segment_buf.ljust(alignment_len, b'\0') # get hash from segment buf - hash_value_summary = hash_value_summary + generate_sha256_hash_hex(elf_segment_buf) + hash_value_summary = generate_sha256_hash_hex(elf_segment_buf) + hash_value_summary # move the read pointer of the file to the original position. if elf_ident.ei_class == elf_info.elfinfo_class_64: @@ -231,15 +244,53 @@ def get_code_segment_from_elf(elf_file_name, out_hash_file_name, sign_data): elf_fp.seek((i_phd + 1) * elf_info.elf32_phdr_size + elf_info.elf32_hdr_size) elf_fp.seek(0) - with os.fdopen(os.open('hash_{}.txt'.format(out_hash_file_name), os.O_RDWR | os.O_CREAT, 0o755), \ + return hash_value_summary + + +def check_if_pack_app(elf_file_name, sign_data, out_hash_file_name, out_hash_file_path): + """ check if app files """ + if "pack-App" in elf_file_name: + out_path = os.path.join(out_hash_file_path, 'hash_{}.txt'.format(out_hash_file_name)) + with os.fdopen(os.open(out_path, os.O_RDWR | os.O_CREAT, 0o755), \ "w+", 0o755) as file_ob: - file_ob.write("mem_hash : {}\n".format(generate_sha256_hash_hex(bytes.fromhex(hash_value_summary)))) - file_ob.write("img_hash : {}".format(generate_sha256_hash_hex(sign_data))) + with os.fdopen(os.open(elf_file_name, os.O_RDWR | os.O_CREAT, 0o755), \ + "rb", 0o755) as tgz_file: + tgz_file_data = tgz_file.read(os.path.getsize(elf_file_name)) + mem_hash = generate_sha256_hash_hex(tgz_file_data) + img_hash = generate_sha256_hash_hex(sign_data) + file_ob.write("mem_hash : {}\n".format(mem_hash)) + file_ob.write("img_hash : {}\n".format(img_hash)) + file_ob.write("mem_hash_base64url : {}\n".format(base64url_encode(bytes.fromhex(mem_hash)).decode('utf-8'))) + file_ob.write("img_hash_base64url : {}".format(base64url_encode(bytes.fromhex(img_hash)).decode('utf-8'))) + return True + + return False + + +def get_code_segment_from_elf(elf_file_name, sign_data, out_hash_file_name, out_hash_file_path): + """ verify ELF header information """ + if whitelist_check(elf_file_name): + logging.error("file name is incorrect.") + return + + if check_if_pack_app(elf_file_name, sign_data, out_hash_file_name, out_hash_file_path) is True: + return + + hash_value_summary = calculate_mem_hash(elf_file_name) + out_path = os.path.join(out_hash_file_path, 'hash_{}.txt'.format(out_hash_file_name)) + mem_hash = generate_sha256_hash_hex(bytes.fromhex(hash_value_summary)) + img_hash = generate_sha256_hash_hex(sign_data) + + with os.fdopen(os.open(out_path, os.O_RDWR | os.O_CREAT, 0o755), "w+", 0o755) as file_ob: + file_ob.write("mem_hash : {}\n".format(mem_hash)) + file_ob.write("img_hash : {}\n".format(img_hash)) + file_ob.write("mem_hash_base64url : {}\n".format(base64url_encode(bytes.fromhex(mem_hash)).decode('utf-8'))) + file_ob.write("img_hash_base64url : {}".format(base64url_encode(bytes.fromhex(img_hash)).decode('utf-8'))) def main(): """ main function """ - get_code_segment_from_elf(sys.argv[1], "test", sys.argv[3]) + get_code_segment_from_elf(sys.argv[1], "test", sys.argv[3], sys.argv[4]) if __name__ == '__main__': diff --git a/build/signtools/manifest.py b/build/signtools/manifest.py index bd6bf90..43214f8 100755 --- a/build/signtools/manifest.py +++ b/build/signtools/manifest.py @@ -27,6 +27,8 @@ PRODUCT_DYN_LIB = 2 PRODUCT_SERVICE_IMAGE = 3 PRODUCT_CLIENT_IMAGE = 4 PRODUCT_DRIVER_IMAGE = 5 +PRODUCT_PYTHON_IMAGE = 6 +PRODUCT_JAVA_IMAGE = 7 class PackUuid: @@ -327,6 +329,20 @@ def parser_manifest(manifest, manifest_data_path, mani_ext, big_endian=False): logging.error("drv's name only can use \ [A-Z] [a-z] [0-9] and '_'") return (False, 0, 0) + if dyn_conf_target_type == 6: + max_service_len = 32 + target_type = PRODUCT_PYTHON_IMAGE + if not re.match(r"^[A-Za-z0-9_]*$", service_name): + logging.error("python dir's name only can use \ + [A-Z] [a-z] [0-9] and '_'") + return (False, 0, 0) + if dyn_conf_target_type == 7: + max_service_len = 32 + target_type = PRODUCT_JAVA_IMAGE + if not re.match(r"^[A-Za-z0-9_]*$", service_name): + logging.error("python dir's name only can use \ + [A-Z] [a-z] [0-9] and '_'") + return (False, 0, 0) if service_name_len > max_service_len: logging.error("service name len cannot larger than %s", str(max_service_len)) @@ -378,6 +394,9 @@ def parser_manifest(manifest, manifest_data_path, mani_ext, big_endian=False): elif target_type == PRODUCT_DYN_LIB: logging.critical("product type is dyn lib") product_name = "".join([uuid_str, service_name, ".so.sec"]) + elif target_type == PRODUCT_PYTHON_IMAGE or target_type == PRODUCT_JAVA_IMAGE: + logging.critical("product type is python or java packing") + product_name = "".join([service_name, ".sec"]) else: logging.error("invalid product type!") return (False, 0, 0) diff --git a/build/signtools/signtool_v3.py b/build/signtools/signtool_v3.py index b588707..39bec9e 100755 --- a/build/signtools/signtool_v3.py +++ b/build/signtools/signtool_v3.py @@ -121,6 +121,8 @@ class AllCfg: sign_alg = "RSA" ta_cert_chain = "" ta_version = 3 + in_path = "" + out_path = "" class PublicCfg: @@ -230,8 +232,24 @@ def check_cfg(cfg): return ret -def gen_header(content_len, key_version, cfg): +def gen_key_version(cfg): + ''' gen key version ''' + if cfg.pub_key_len == '4096': + return int(0x0302) + elif cfg.pub_key_len == '3072': + return int(0x0202) + elif cfg.pub_key_len == '2048': + return int(0x0002) + elif cfg.pub_key_len == '': + return int(0x0000) + + logging.error("unhandled pulic key len %s", cfg.pub_key_len) + raise RuntimeError + + +def gen_header(content_len, cfg): ''' gen header by endian ''' + key_version = gen_key_version(cfg) if SING_BIG_ENDIAN: head_tag = '>IHHII' else: @@ -307,12 +325,15 @@ def encrypt_aes_key(pubkey_path, in_data, out_path): return -def gen_signature(cfg, uuid_str, raw_data, raw_data_path, hash_file_path, \ - out_file_path, out_path, key_info_data): - gen_ta_signature(cfg, uuid_str, raw_data, raw_data_path, \ - hash_file_path, out_file_path, out_path, key_info_data, SING_BIG_ENDIAN) - os.chmod(out_file_path, stat.S_IWUSR | stat.S_IRUSR) - return +def gen_signature(cfg, uuid_str, data_for_sign, key_info_data, temp_path): + ''' gen signature ''' + raw_data_path = os.path.join(temp_path, "dataForSign.bin") + hash_file_path = os.path.join(temp_path, "rawDataHash.bin") + signature_path = os.path.join(temp_path, "signature.bin") + + gen_ta_signature(cfg, uuid_str, data_for_sign, raw_data_path, \ + hash_file_path, signature_path, cfg.out_path, key_info_data, SING_BIG_ENDIAN, temp_path) + os.chmod(signature_path, stat.S_IWUSR | stat.S_IRUSR) def gen_raw_data(manifest_data_path, manifest_ext_path, elf_file_path, \ @@ -322,7 +343,8 @@ def gen_raw_data(manifest_data_path, manifest_ext_path, elf_file_path, \ elf_size = os.path.getsize(elf_file_path) config_size = 0 - verify_elf_header(elf_file_path) + if "pack-App" not in elf_file_path: + verify_elf_header(elf_file_path) fd_op = os.open(raw_file_path, os.O_WRONLY | os.O_CREAT, \ stat.S_IWUSR | stat.S_IRUSR) @@ -386,7 +408,7 @@ def parser_api_level(mk_compile_cfg, cmake_compile_cfg): elif os.path.exists(cmake_compile_cfg): compile_cfg_file = cmake_compile_cfg else: - logging.error("Build config file doesn't exist, ignore it") + logging.critical("Build config file doesn't exist, ignore it") return default_api_level with open(compile_cfg_file) as file_op: @@ -398,11 +420,14 @@ def parser_api_level(mk_compile_cfg, cmake_compile_cfg): logging.critical("ta_api_level = %s", value[0]) return value[0] - logging.error("Build Config file doesn't define API_LEVEL") + logging.critical("Build Config file doesn't define API_LEVEL") return default_api_level -def update_api_level(mk_compile_cfg, cmake_compile_cfg, manifest): +def update_api_level(cfg, manifest): + ''' update api level ''' + mk_compile_cfg = os.path.join(cfg.in_path, "config.mk") + cmake_compile_cfg = os.path.join(cfg.in_path, "config.cmake") data = '' with open(manifest, 'r') as file_op: for line in file_op: @@ -434,7 +459,9 @@ def update_otrp_flag(manifest): file_op.close() -def gen_data_for_sign(header, key_data, raw_file): +def gen_data_for_sign(cfg, content_len, key_data, raw_file): + ''' gen data for sign ''' + header = gen_header(int(content_len), cfg) raw_file_len = os.path.getsize(raw_file) with open(raw_file, 'rb') as raw_fp: raw_data = raw_fp.read(raw_file_len) @@ -445,20 +472,6 @@ def gen_data_for_sign(header, key_data, raw_file): return data_sign -def gen_key_version(cfg): - if cfg.pub_key_len == '4096': - return int(0x0302) - elif cfg.pub_key_len == '3072': - return int(0x0202) - elif cfg.pub_key_len == '2048': - return int(0x0002) - elif cfg.pub_key_len == '': - return int(0x0000) - - logging.error("unhandled pulic key len %s", cfg.pub_key_len) - raise RuntimeError - - def pack_signature(signature_path, signature_size): add_size = 72 - signature_size with open(signature_path, 'rb+') as signature_file: @@ -500,52 +513,122 @@ def get_sign_cert_block_buffer(cfg, signature_path, signature_size): return sign_verify_buf -def gen_sec_image(in_path, out_path, cfg): - # temporary files - temp_path = os.path.join(out_path, "temp") - shutil.rmtree(temp_path, ignore_errors=True) - os.mkdir(temp_path) - os.chmod(temp_path, stat.S_IRWXU) - key_info_path = os.path.join(temp_path, "KeyInfo") - enc_key_path = os.path.join(temp_path, "KeyInfo.enc") - raw_file_path = os.path.join(temp_path, "rawData") - enc_raw_path = os.path.join(temp_path, "rawData.enc") - 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") - hash_path = os.path.join(temp_path, "rawDataHash.bin") - - # mandentory input files - manifest_path = os.path.join(in_path, "manifest.txt") - elf_file_path = os.path.join(in_path, "libcombine.so") - mk_cfg_path = os.path.join(in_path, "config.mk") - cmake_cfg_path = os.path.join(in_path, "config.cmake") - dyn_conf_xml_file_path = os.path.join(in_path, "dyn_perm.xml") +def get_ta_sign_len(cfg): + ''' get ta sign len ''' + if cfg.sign_type == '4': + return 9219 + if cfg.sign_type == '5': + return 0 + if cfg.sign_type == '6': + return 9227 + if int(cfg.sign_key_len) == 256: + return 72 + return int(cfg.sign_key_len) / 8 + + +def parser_config(cfg, manifest_path, manifest_ext_path): + ''' parser config ''' + dyn_conf_xml_file_path = os.path.join(cfg.in_path, "dyn_perm.xml") tag_parse_dict_file_path = os.path.join(os.getcwd(), "tag_parse_dict.csv") - xml_config_path = os.path.join(in_path, "configs.xml") - auth_xml_file_path = os.path.join(in_path, "auth_config.xml") + if os.path.exists(dyn_conf_xml_file_path): + # V3.1 ta/drv do not need manifest_ext + if not os.path.exists(cfg.config_path): + from dyn_conf_parser import parser_dyn_conf + parser_dyn_conf(dyn_conf_xml_file_path, manifest_ext_path, \ + tag_parse_dict_file_path, cfg.in_path) + else: + if check_if_is_drv(manifest_path) == 1: + if not os.path.exists(cfg.config_path): + ans = "gpd.ta.dynConf:00000\n" + manifest_ext_path_fd = os.open(manifest_ext_path, \ + os.O_RDWR, 0o600) + with os.fdopen(manifest_ext_path_fd, 'a+') as mani_ext_fp: + mani_ext_fp.write(ans) + + # parser auth config xml: the auth info must be packed in the end of manifest_ext. + auth_xml_file_path = os.path.join(cfg.in_path, "auth_config.xml") + if os.path.exists(auth_xml_file_path): + from auth_conf_parser import parser_auth_xml + parser_auth_xml(auth_xml_file_path, manifest_ext_path, SING_BIG_ENDIAN) + + +def get_key_info_data(cfg, raw_file_path, key_data_path, raw_data_path): + ''' get key info data ''' + is_encrypt_sec = True + if cfg.public_key == "" or cfg.pub_key_len == "": + is_encrypt_sec = False + + if is_encrypt_sec is True: + # generate AES key info to encrypt raw data + key_data, iv_data, key_info_data = gen_aes_key_info(cfg) + encrypt_aes_key(cfg.public_key, key_info_data, key_data_path) + aes_encrypt(key_data, iv_data, raw_file_path, raw_data_path) + else: + gen_sign_alg_info(cfg, key_data_path) + with open(key_data_path, 'rb') as key_info_fp: + key_info_data = key_info_fp.read(os.path.getsize(key_data_path)) - ta_cert_path = cfg.ta_cert_chain + return key_info_data + + +def get_content_len(cfg, key_data_path, raw_data_path): + ''' get content len ''' + sign_len = get_ta_sign_len(cfg) if cfg.ta_version == 5: + ta_cert_path = cfg.ta_cert_chain if cfg.sign_key_type == TYPE_PUBKEY: ta_cert_len = 0 else: ta_cert_len = os.path.getsize(ta_cert_path) + content_len = os.path.getsize(key_data_path) \ + + 4 + 4 + ta_cert_len + sign_len \ + + os.path.getsize(raw_data_path) + else: + content_len = os.path.getsize(key_data_path) \ + + sign_len \ + + os.path.getsize(raw_data_path) + + return content_len + + +def get_data_path(cfg, temp_path): + ''' get data path ''' + enc_key_path = os.path.join(temp_path, "KeyInfo.enc") + enc_raw_path = os.path.join(temp_path, "rawData.enc") + key_info_path = os.path.join(temp_path, "KeyInfo") + raw_file_path = os.path.join(temp_path, "rawData") is_encrypt_sec = True if cfg.public_key == "" or cfg.pub_key_len == "": is_encrypt_sec = False + if is_encrypt_sec is True: + key_data_path = enc_key_path + raw_data_path = enc_raw_path + else: + key_data_path = key_info_path + raw_data_path = raw_file_path + + return key_data_path, raw_data_path + + +def prepare_data(cfg, temp_path): + ''' get sec image ''' + manifest_path = os.path.join(cfg.in_path, "manifest.txt") + manifest_data_path = os.path.join(temp_path, "manifestData.bin") + manifest_ext_path = os.path.join(temp_path, "manifestExt.bin") + elf_file_path = os.path.join(cfg.in_path, "libcombine.so") + raw_file_path = os.path.join(temp_path, "rawData") + key_data_path, raw_data_path = get_data_path(cfg, temp_path) + # 1. parser_manifest - manifest_info = process_manifest_file(xml_config_path, \ + manifest_info = process_manifest_file(os.path.join(cfg.in_path, "configs.xml"), \ manifest_path, manifest_data_path, manifest_ext_path, SING_BIG_ENDIAN) - uuid_str = manifest_info.uuid_str if manifest_info.ret is False: raise RuntimeError # 2. update_api_level - update_api_level(mk_cfg_path, cmake_cfg_path, manifest_ext_path) + update_api_level(cfg, manifest_ext_path) # 3. update_otrp_flag if cfg.otrp_flag == "1": @@ -553,155 +636,152 @@ def gen_sec_image(in_path, out_path, cfg): update_otrp_flag(manifest_ext_path) # 4. parser_dyn_conf - if os.path.exists(dyn_conf_xml_file_path): - # V3.1 ta/drv do not need manifest_ext - if not os.path.exists(cfg.config_path): - from dyn_conf_parser import parser_dyn_conf - parser_dyn_conf(dyn_conf_xml_file_path, manifest_ext_path, \ - tag_parse_dict_file_path, in_path) - else: - if check_if_is_drv(manifest_path) == 1: - if not os.path.exists(cfg.config_path): - ans = "gpd.ta.dynConf:00000\n" - manifest_ext_path_fd = os.open(manifest_ext_path, \ - os.O_RDWR, 0o600) - with os.fdopen(manifest_ext_path_fd, 'a+') as mani_ext_fp: - mani_ext_fp.write(ans) - - # parser auth config xml: the auth info must be packed in the end of manifest_ext. - if os.path.exists(auth_xml_file_path): - from auth_conf_parser import parser_auth_xml - parser_auth_xml(auth_xml_file_path, manifest_ext_path, SING_BIG_ENDIAN) + parser_config(cfg, manifest_path, manifest_ext_path) # 5. gen_raw_data gen_raw_data(manifest_data_path, manifest_ext_path, elf_file_path, \ cfg.config_path, raw_file_path, cfg.ta_version) - if cfg.sign_type == '4': - sign_len = 9219 - elif cfg.sign_type == '5': - sign_len = 0 - elif cfg.sign_type == '6': - sign_len = 9227 - else: - if int(cfg.sign_key_len) == 256: - sign_len = 72 - else: - sign_len = int(cfg.sign_key_len) / 8 - # 6. gen aes key, and encrypt aes key with RSA key, # and encrypt raw data with aes key - if is_encrypt_sec is True: - # generate AES key info to encrypt raw data - key_data, iv_data, key_info_data = gen_aes_key_info(cfg) - encrypt_aes_key(cfg.public_key, key_info_data, enc_key_path) - aes_encrypt(key_data, iv_data, raw_file_path, enc_raw_path) - - # generate Main Header - if cfg.ta_version == 5: - content_len = os.path.getsize(enc_key_path) \ - + 4 + 4 + ta_cert_len + sign_len \ - + os.path.getsize(enc_raw_path) - else: - content_len = os.path.getsize(enc_key_path) \ - + sign_len \ - + os.path.getsize(enc_raw_path) - else: - gen_sign_alg_info(cfg, key_info_path) - # generate Main Header - if cfg.ta_version == 5: - content_len = os.path.getsize(key_info_path) \ - + 4 + 4 + ta_cert_len + sign_len \ - + os.path.getsize(raw_file_path) - else: - content_len = os.path.getsize(key_info_path) \ - + sign_len \ - + os.path.getsize(raw_file_path) - with open(key_info_path, 'rb') as key_info_fp: - key_info_data = key_info_fp.read(os.path.getsize(key_info_path)) + key_info_data = get_key_info_data(cfg, raw_file_path, key_data_path, raw_data_path) - key_version = gen_key_version(cfg) - header = gen_header(int(content_len), key_version, cfg) - data_for_sign = gen_data_for_sign(header, key_info_data, raw_file_path) - - uuid_str = uuid_str[0:36] - logging.critical("uuid str %s", uuid_str) - - # 7. gen signature - gen_signature(cfg, uuid_str, data_for_sign, data_for_sign_path, \ - hash_path, signature_path, out_path, key_info_data) + # 7. generate content_len and data_for_sign + content_len = get_content_len(cfg, key_data_path, raw_data_path) + data_for_sign = gen_data_for_sign(cfg, content_len, key_info_data, raw_file_path) + # 8. parse code segment if os.path.exists("get_ta_elf_hash.py"): + uuid_str = manifest_info.uuid_str + uuid_str = uuid_str[0:36] if os.path.exists(elf_file_path): from get_ta_elf_hash import get_code_segment_from_elf - get_code_segment_from_elf(elf_file_path, uuid_str, data_for_sign) + get_code_segment_from_elf(elf_file_path, data_for_sign, uuid_str, cfg.out_path) + + if manifest_info.manifest_txt_exist is False and os.path.exists(manifest_path): + os.remove(manifest_path) + + return manifest_info, data_for_sign, key_info_data - # 8. pack sec img: header || key || signature || raw_data + +def update_content_len(cfg, key_data_path, raw_data_path, signature_path): + ''' update content len ''' + sign_len = get_ta_sign_len(cfg) signature_size = os.path.getsize(signature_path) + content_len = get_content_len(cfg, key_data_path, raw_data_path) if sign_len == 72: if signature_size != 72: pack_signature(signature_path, signature_size) elif sign_len == 0: sign_len = signature_size # generate Main Header - if is_encrypt_sec is True: - key_data_path = enc_key_path - raw_data_path = enc_raw_path - else: - key_data_path = key_info_path - raw_data_path = raw_file_path content_len = os.path.getsize(key_data_path) \ + sign_len \ + os.path.getsize(raw_data_path) - header = gen_header(int(content_len), key_version, cfg) - sec_img_path = os.path.join(out_path, manifest_info.product_name) + return content_len + + +def pack_sec_img(cfg, manifest_info, temp_path): + ''' pack sec img ''' + signature_path = os.path.join(temp_path, "signature.bin") + key_data_path, raw_data_path = get_data_path(cfg, temp_path) + + content_len = update_content_len(cfg, key_data_path, raw_data_path, signature_path) + header = gen_header(int(content_len), cfg) + sec_img_path = os.path.join(cfg.out_path, manifest_info.product_name) fd_image = os.open(sec_img_path, os.O_WRONLY | os.O_CREAT, \ stat.S_IWUSR | stat.S_IRUSR) sec_image = os.fdopen(fd_image, "wb") # write to sec file [1.header info] sec_image.write(header) - if is_encrypt_sec is True: - # 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)) - else: - key_info_size = os.path.getsize(key_info_path) - with open(key_info_path, 'rb') as key_info_fp: - sec_image.write(key_info_fp.read(key_info_size)) + with open(key_data_path, 'rb') as key_data_fp: + sec_image.write(key_data_fp.read(os.path.getsize(key_data_path))) # write to sec file [3.signature] if cfg.ta_version == 5: - signature_size = os.path.getsize(signature_path) - sign_cert_buf = get_sign_cert_block_buffer(cfg, signature_path, signature_size) + sign_cert_buf = get_sign_cert_block_buffer(cfg, signature_path, os.path.getsize(signature_path)) sec_image.write(sign_cert_buf) else: - signature_size = os.path.getsize(signature_path) with open(signature_path, 'rb') as signature_file: - sec_image.write(signature_file.read(signature_size)) - if is_encrypt_sec is True: - # 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)) - else: - raw_file_size = os.path.getsize(raw_file_path) - with open(raw_file_path, 'rb') as raw_file_data: - sec_image.write(raw_file_data.read(raw_file_size)) + sec_image.write(signature_file.read(os.path.getsize(signature_path))) + with open(raw_data_path, 'rb') as raw_data_fp: + sec_image.write(raw_data_fp.read(os.path.getsize(raw_data_path))) sec_image.truncate(int(SEC_HEADER_BYTES) + int(content_len)) sec_image.close() - logging.critical("=========================SUCCESS============================") logging.critical("generate sec(common format) load image success: ") logging.critical(sec_img_path) logging.critical("============================================================") - if manifest_info.manifest_txt_exist is False and os.path.exists(manifest_path): - os.remove(manifest_path) - #remove temp files - shutil.rmtree(temp_path) - return +def gen_sec_image(temp_path, cfg): + ''' get sec image ''' + shutil.rmtree(temp_path, ignore_errors=True) + os.mkdir(temp_path) + os.chmod(temp_path, stat.S_IRWXU) + + manifest_info, data_for_sign, key_info_data = prepare_data(cfg, temp_path) + + uuid_str = manifest_info.uuid_str + uuid_str = uuid_str[0:36] + logging.critical("uuid str %s", uuid_str) + gen_signature(cfg, uuid_str, data_for_sign, key_info_data, temp_path) + + pack_sec_img(cfg, manifest_info, temp_path) + + +def print_file(file_path): + ''' print file content ''' + file_size = os.path.getsize(file_path) + with open(file_path, 'rb') as file_fd: + file_info = file_fd.read(file_size) + buf = [hex(int(i)) for i in file_info] + output = " ".join(buf) + logging.error("%s", output) + + +def check_signature(temp_path, check_path): + ''' check ta signature ''' + temp_hash_path = os.path.join(temp_path, "rawDataHash.bin") + check_hash_path = os.path.join(check_path, "rawDataHash.bin") + + temp_hash_size = os.path.getsize(temp_hash_path) + check_hash_size = os.path.getsize(check_hash_path) + if temp_hash_size != check_hash_size: + logging.error("hash file size is diff: %d, %d", temp_hash_size, check_hash_size) + return -1 + + with open(temp_hash_path, 'rb') as temp_hash_fp: + temp_hash_info = temp_hash_fp.read(temp_hash_size) + with open(check_hash_path, 'rb') as check_hash_fp: + check_hash_info = check_hash_fp.read(check_hash_size) + if temp_hash_info != check_hash_info: + logging.error("hash file content is diff:") + logging.error("temp_hash_info:") + print_file(temp_hash_path) + logging.error("check_hash_info:") + print_file(check_hash_path) + return -1 + + return 0 + + +def check_inout_path(in_path, out_path): + ''' check inpath or outpath valid ''' + if not os.path.exists(in_path): + logging.error("input_path does not exist.") + return 1 + if not os.path.exists(out_path): + logging.error("out_path does not exist.") + return 1 + if whitelist_check(in_path): + logging.error("input_path is incorrect.") + return 1 + if whitelist_check(out_path): + logging.error("out_path is incorrect.") + return 1 + + return 0 def main(): @@ -737,27 +817,35 @@ def main(): if check_cfg(cfg): logging.error("the configuration file field is incorrect.") exit() - in_path = os.path.realpath(args.in_path) - out_path = os.path.realpath(args.out_path) - if not os.path.exists(in_path): - logging.error("input_path does not exist.") - exit() - if not os.path.exists(out_path): - logging.error("out_path does not exist.") - exit() - if whitelist_check(in_path): - logging.error("input_path is incorrect.") - exit() - if whitelist_check(out_path): - logging.error("out_path is incorrect.") + cfg.in_path = os.path.realpath(args.in_path) + cfg.out_path = os.path.realpath(args.out_path) + if check_inout_path(cfg.in_path, cfg.out_path): exit() os.chdir(sign_tool_dir) if cfg.re_sign_flag == "1": from re_generate_signature import re_sign_sec_img - re_sign_sec_img(in_path, out_path, cfg) + re_sign_sec_img(cfg.in_path, cfg.out_path, cfg) else: - gen_sec_image(in_path, out_path, cfg) + if SING_BIG_ENDIAN: + retry_time = 0 + result = -1 + while retry_time <= 3 and result != 0: + temp_path = os.path.join(cfg.out_path, "temp") + check_path = os.path.join(cfg.out_path, "check") + gen_sec_image(temp_path, cfg) + gen_sec_image(check_path, cfg) + result = check_signature(temp_path, check_path) + shutil.rmtree(check_path) + shutil.rmtree(temp_path) + retry_time += 1 + if retry_time > 3 and result != 0: + raise RuntimeError + else: + temp_path = os.path.join(cfg.out_path, "temp") + gen_sec_image(temp_path, cfg) + #remove temp files + shutil.rmtree(temp_path) if __name__ == '__main__': diff --git a/build/signtools/tag_parse_dict.csv b/build/signtools/tag_parse_dict.csv index 22040ea..e42e44a 100644 --- a/build/signtools/tag_parse_dict.csv +++ b/build/signtools/tag_parse_dict.csv @@ -8,6 +8,7 @@ drv_perm/drv_basic_info/thread_limit,6,TYPE_INT, drv_perm/drv_basic_info/upgrade,7,TYPE_BOOL, drv_perm/drv_basic_info/virt2phys,8,TYPE_BOOL, drv_perm/drv_basic_info/exception_mode,9,TYPE_CHAR, +drv_perm/drv_basic_info/ioremap_ns,38,TYPE_BOOL, drv_perm/drv_io_map/,10,TYPE_CLASS, drv_perm/drv_io_map/item/,11,TYPE_CLASS, drv_perm/drv_io_map/item/chip_type,12,TYPE_CHAR, @@ -25,6 +26,8 @@ drv_perm/map_nosecure/,23,TYPE_CLASS, drv_perm/map_nosecure/item/,24,TYPE_CLASS, drv_perm/map_nosecure/item/chip_type,25,TYPE_CHAR, drv_perm/map_nosecure/item/uuid,26,TYPE_CHAR, +drv_perm/map_regions/,36,TYPE_CLASS, +drv_perm/map_regions/regions,37,TYPE_CHAR, drv_perm/drv_cmd_perm_info/,27,TYPE_CLASS, drv_perm/drv_cmd_perm_info/item/,28,TYPE_CLASS, drv_perm/drv_cmd_perm_info/item/cmd,29,TYPE_CHAR,{gpd.ta.service_name}.csv @@ -43,6 +46,7 @@ ConfigInfo/drv_perm/drv_basic_info/thread_limit,6,TYPE_INT, ConfigInfo/drv_perm/drv_basic_info/upgrade,7,TYPE_BOOL, ConfigInfo/drv_perm/drv_basic_info/virt2phys,8,TYPE_BOOL, ConfigInfo/drv_perm/drv_basic_info/exception_mode,9,TYPE_CHAR, +ConfigInfo/drv_perm/drv_basic_info/ioremap_ns,38,TYPE_BOOL, ConfigInfo/drv_perm/drv_io_map/,10,TYPE_CLASS, ConfigInfo/drv_perm/drv_io_map/item/,11,TYPE_CLASS, ConfigInfo/drv_perm/drv_io_map/item/chip_type,12,TYPE_CHAR, @@ -60,6 +64,8 @@ ConfigInfo/drv_perm/map_nosecure/,23,TYPE_CLASS, ConfigInfo/drv_perm/map_nosecure/item/,24,TYPE_CLASS, ConfigInfo/drv_perm/map_nosecure/item/chip_type,25,TYPE_CHAR, ConfigInfo/drv_perm/map_nosecure/item/uuid,26,TYPE_CHAR, +ConfigInfo/drv_perm/map_regions/,36,TYPE_CLASS, +ConfigInfo/drv_perm/map_regions/regions,37,TYPE_CHAR, ConfigInfo/drv_perm/drv_cmd_perm_info/,27,TYPE_CLASS, ConfigInfo/drv_perm/drv_cmd_perm_info/item/,28,TYPE_CLASS, ConfigInfo/drv_perm/drv_cmd_perm_info/item/cmd,29,TYPE_CHAR,{gpd.ta.service_name}.csv diff --git a/include/CA/tee_client_api.h b/include/CA/tee_client_api.h index f9ce68e..8f1c219 100644 --- a/include/CA/tee_client_api.h +++ b/include/CA/tee_client_api.h @@ -14,10 +14,6 @@ #ifndef _TEE_CLIENT_API_H_ #define _TEE_CLIENT_API_H_ -#ifndef LOG_TAG -#define LOG_TAG NULL -#endif - #ifdef LOG_NDEBUG #undef LOG_NDEBUG #endif diff --git a/include/TA/huawei_ext/crypto_device_key_wrapper.h b/include/TA/huawei_ext/crypto_device_key_wrapper.h deleted file mode 100644 index 2c8ba9e..0000000 --- a/include/TA/huawei_ext/crypto_device_key_wrapper.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved. - * Licensed under the Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR - * PURPOSE. - * See the Mulan PSL v2 for more details. - * Description: soft device key engine - */ -#ifndef __CRYPTO_DEVICE_KEY_WRAPPER_H__ -#define __CRYPTO_DEVICE_KEY_WRAPPER_H__ - -#include -#include - -/* - * Get oem huk. - * - * @param huk [OUT] The oem huk buffer - * @param key [IN] The hmac key buffer - * @param key_size [IN] The length of hmac key buffer - * - * @return 0: Get oem huk success - * @return -1: Get oem huk failed - */ -int32_t get_class_oem_huk(uint8_t *huk, const uint8_t *key, uint32_t key_size); - -#endif diff --git a/include/TA/huawei_ext/crypto_ec_wrapper.h b/include/TA/huawei_ext/crypto_ec_wrapper.h index 934fc40..2f74078 100644 --- a/include/TA/huawei_ext/crypto_ec_wrapper.h +++ b/include/TA/huawei_ext/crypto_ec_wrapper.h @@ -73,7 +73,7 @@ int32_t derive_ecc_private_key_from_huk(ecc_priv_key_t *priv, const uint8_t *sec * Convert the ecc_pub_key_t structure passed in by the user into ecc public key buffer. * * @param out [OUT] The ecc public key buffer - * @param outlen [IN/OUT] The length of ecc public key buffer + * @param outlen [IN] The length of ecc public key buffer * @param pub [IN] The ecc public key structure * * @return -1: Export ecc public key failed @@ -122,7 +122,7 @@ int32_t get_next_tlv(uint32_t *type, uint32_t *header_len, const uint8_t *buf, u * Use ECC algorithm to sign user data. * * @param signature [OUT] The signature of input data - * @param sig_siz [IN/OUT] The length of signature + * @param sig_siz [IN] The length of signature * @param in [IN] The data to be sign * @param in_len [IN] The length of input data * @param priv [IN] The ecc private key structure diff --git a/include/TA/huawei_ext/crypto_ec_x509_wrapper.h b/include/TA/huawei_ext/crypto_ec_x509_wrapper.h index 73e2832..f99d24b 100644 --- a/include/TA/huawei_ext/crypto_ec_x509_wrapper.h +++ b/include/TA/huawei_ext/crypto_ec_x509_wrapper.h @@ -21,7 +21,7 @@ * Recover the root certificate. * * @param cert [OUT] The certificate buffer - * @param cert_len [IN/OUT] The length of certificate buffer + * @param cert_len [IN] The length of certificate buffer * @param priv [IN] The private key structure * @param keytype [IN] The keytype of private key * diff --git a/include/TA/huawei_ext/crypto_inner_wrapper.h b/include/TA/huawei_ext/crypto_inner_wrapper.h index 01a171f..a8e4d50 100644 --- a/include/TA/huawei_ext/crypto_inner_wrapper.h +++ b/include/TA/huawei_ext/crypto_inner_wrapper.h @@ -20,7 +20,7 @@ * Get common name from certificate. * * @param name [OUT] The common name buffer - * @param name_size [IN/OUT] The length of common name buffer + * @param name_size [IN] The length of common name buffer * @param cert [IN] The certificate buffer * @param cert_len [IN] The length of certificate buffer * @@ -33,7 +33,7 @@ int32_t get_subject_CN(uint8_t *name, uint32_t name_size, const uint8_t *cert, u * Get organization name from certificate. * * @param name [OUT] The organization name buffer - * @param name_size [IN/OUT] The length of organization name buffer + * @param name_size [IN] The length of organization name buffer * @param cert [IN] The certificate buffer * @param cert_len [IN] The length of certificate buffer * diff --git a/include/TA/huawei_ext/crypto_x509_wrapper.h b/include/TA/huawei_ext/crypto_x509_wrapper.h index 830e7dc..11590be 100644 --- a/include/TA/huawei_ext/crypto_x509_wrapper.h +++ b/include/TA/huawei_ext/crypto_x509_wrapper.h @@ -73,10 +73,10 @@ int32_t import_pub_from_sp(void *pub, const uint8_t *in, uint32_t inlen); int32_t get_subject_public_key(uint8_t *pub, const uint8_t *cert, uint32_t cert_len); /* - * Get public key from certificate. + * Get public key from certificate, with pub buffer size check. * * @param pub [OUT] The public key buffer - * @param pub_size [IN/OUT] The length of public key buffer + * @param pub_size [IN] The length of public key buffer * @param cert [IN] The certificate buffer * @param cert_len [IN] The length of certificate buffer * @@ -88,12 +88,12 @@ int32_t get_subject_public_key_new(uint8_t *pub, uint32_t pub_size, const uint8_ /* * Get valid date from certificate. * - * @param vd [OUT] The valid date structure + * @param vd [OUT] The valid data structure * @param cert [IN] The certificate buffer * @param cert_len [IN] The length of certificate buffer * * @return 0: Get valid date success - * @return -1: Get valid date failed + * @return -1: Get valid data failed */ int32_t get_validity_from_cert(validity_period_t *vd, uint8_t *cert, uint32_t cert_len); @@ -101,7 +101,7 @@ int32_t get_validity_from_cert(validity_period_t *vd, uint8_t *cert, uint32_t ce * Get common name from certificate. * * @param name [OUT] The common name buffer - * @param name_size [IN/OUT] The length of common name buffer + * @param name_size [IN] The length of common name buffer * @param cert [IN] The certificate buffer * @param cert_len [IN] The length of certificate buffer * @@ -114,7 +114,7 @@ int32_t get_subject_x509_cn(uint8_t *name, uint32_t name_size, const uint8_t *ce * Get organization name from certificate. * * @param name [OUT] The organization name buffer - * @param name_size [IN/OUT] The length of organization name buffer + * @param name_size [IN] The length of organization name buffer * @param cert [IN] The certificate buffer * @param cert_len [IN] The length of certificate buffer * @@ -127,7 +127,7 @@ int32_t get_subject_x509_ou(uint8_t *name, uint32_t name_size, const uint8_t *ce * Get serial number from certificate. * * @param serial_number [OUT] The serial number buffer - * @param serial_number_size [IN/OUT] The length of serial number buffer + * @param serial_number_size [IN] The length of serial number buffer * @param cert [IN] The certificate buffer * @param cert_len [IN] The length of certificate buffer * @@ -141,7 +141,7 @@ int32_t get_serial_number_from_cert(uint8_t *serial_number, uint32_t serial_numb * Get issuer from certificate. * * @param issuer [OUT] The issuer buffer - * @param issuer_size [IN/OUT] The length of issuer buffer + * @param issuer_size [IN] The length of issuer buffer * @param cert [IN] The certificate buffer * @param cert_len [IN] The length of certificate buffer * @@ -163,7 +163,7 @@ int32_t get_issuer_from_cert(uint8_t *issuer, uint32_t issuer_size, uint8_t *crl * @return -1: failed * @return >0: check success */ -int x509_cert_chain_validate(uint8_t *root_cert, uint32_t root_cert_len, - uint8_t *second_cert, uint32_t second_cert_len, - uint8_t *leaf_cert, uint32_t leaf_cert_len); +int x509_cert_chain_validate(const uint8_t *root_cert, uint32_t root_cert_len, + const uint8_t *second_cert, uint32_t second_cert_len, + const uint8_t *leaf_cert, uint32_t leaf_cert_len); #endif diff --git a/include/TA/huawei_ext/permsrv_api_legacy.h b/include/TA/huawei_ext/permsrv_api_legacy.h index e76f5b5..5167144 100644 --- a/include/TA/huawei_ext/permsrv_api_legacy.h +++ b/include/TA/huawei_ext/permsrv_api_legacy.h @@ -16,6 +16,7 @@ #include "tee_defines.h" +TEE_Result TEE_EXT_GetRpmbThreshold(const TEE_UUID *uuid, uint32_t *result); TEE_Result TEE_EXT_crl_cert_process(const char *crl_cert, uint32_t crl_cert_size); TEE_Result TEE_EXT_ta_ctrl_list_process(const char *ctrl_list, uint32_t ctrl_list_size); #endif diff --git a/include/TA/huawei_ext/tee_ext_api.h b/include/TA/huawei_ext/tee_ext_api.h index 309abe3..29add2a 100644 --- a/include/TA/huawei_ext/tee_ext_api.h +++ b/include/TA/huawei_ext/tee_ext_api.h @@ -43,7 +43,10 @@ extern "C" { typedef struct ta_caller_info { uint32_t session_type; union { - TEE_UUID caller_uuid; + struct { + TEE_UUID caller_uuid; + uint32_t group_id; + }; uint8_t ca_info[RESERVED_BUF_SIZE]; } caller_identity; uint8_t smc_from_kernel_mode; @@ -61,6 +64,26 @@ typedef struct ta_caller_info { */ TEE_Result tee_ext_get_caller_info(caller_info *caller_info_data, uint32_t length); +/* + * Get group info of current service + * + * @param group_id [OUT] group info to be returned + * + * return TEE_SUCCESS operation success + * return others failed to get group info + */ +TEE_Result tee_ext_get_group_id(uint32_t *group_id); + +/* + * Get nsid of current service + * + * @param nsid [OUT] nsid to be returned + * + * return TEE_SUCCESS operation success + * return others failed to get nsid + */ +TEE_Result tee_ext_get_nsid(uint32_t *nsid); + /* * verify TA's caller's identify * TA can call this API to add caller's info, diff --git a/include/TA/huawei_ext/tee_hw_ext_api_legacy.h b/include/TA/huawei_ext/tee_hw_ext_api_legacy.h index 34e480a..0e5f379 100644 --- a/include/TA/huawei_ext/tee_hw_ext_api_legacy.h +++ b/include/TA/huawei_ext/tee_hw_ext_api_legacy.h @@ -17,16 +17,6 @@ #include "tee_defines.h" #include "tee_crypto_api.h" -/* - * ta version anti rollback api - * - * @param ta_version [IN] version to be checked - * - * @return TEE_SUCCESS check result is OK - * @return others check ta version failed - */ -TEE_Result TEE_EXT_TA_version_check(uint32_t ta_version); - /* * check wheather target TA(uuid) has permission to invoke target command * this feature is only supported by TA with certificate @@ -39,16 +29,6 @@ TEE_Result TEE_EXT_TA_version_check(uint32_t ta_version); */ TEE_Result TEE_EXT_CheckInvokePermission(const TEE_UUID *uuid, uint32_t cmd); -/* - * get sharemem of verify boot information - * - * @param buffer [OUT] the address to save verify boot info - * @param size [IN] length of buffer - * - * @return 0 means success, others means failed - */ -TEE_Result TEE_EXT_GetVerifyBootInfo(char *buffer, uint32_t size); - /* * derive key from device rootkey and UUID of the current task * @@ -63,19 +43,6 @@ TEE_Result TEE_EXT_GetVerifyBootInfo(char *buffer, uint32_t size); */ TEE_Result TEE_EXT_DeriveTARootKey(const uint8_t *salt, uint32_t size, uint8_t *key, uint32_t key_size); -/* - * get rot key for multiple platforms - * - * @param enc_key [IN] encrypted rot key or NULL - * @param en_key_size [IN] encrypted rot key buff len or zero - * @param key [OUT]rot key buff pointer - * @param key_size [IN/OUT] rot key buffer length - * - * @return 0 get rot key success - * @return -1 get rot key failed - */ -int32_t TEE_EXT_GetRoT(const uint8_t *enc_key, uint32_t en_key_size, uint8_t *key, uint32_t *key_size); - /* * get device unique id in TEE * @@ -87,36 +54,6 @@ int32_t TEE_EXT_GetRoT(const uint8_t *enc_key, uint32_t en_key_size, uint8_t *ke */ TEE_Result TEE_EXT_GetDeviceUniqueId(uint8_t *device_unique_id, uint32_t *length); -TEE_Result TEE_EXT_GetSeCapability(const TEE_UUID *uuid, uint64_t *result); - -/* - * @ingroup TEE_EXT_API - * @brief get shared memory infomation of SecFlash - * - * @param buffer [OUT] the address to save SecFlash shared memory info - * @param length [IN] length of buffer - * - * @retval NA - */ -TEE_Result TEE_EXT_GetSecFlashShareMem(char *buffer, uint32_t size); - -/* - * @ingroup share memory - * @brief get sharemem of verify boot information - * - * @par - * @param buffer [OUT] the address to save verify boot info - * @param size [IN] length of buffer - * - * @retval NA - * - * @par dependence: - * @li tee_ext_api.h - * @see - * @since V100R008C00 - */ -TEE_Result TEE_EXT_GetTrustBootImgInfo(char *buffer, uint32_t size); - /* * @ingroup derive key for keymaster * @brief using root key to derive key for keymaster @@ -234,16 +171,6 @@ TEE_Result TEE_EXT_HwiMsgDeregister(uint32_t hwi); */ uint32_t TEE_EXT_HwiMsgWait(void); -/* - * @ingroup TEE_HW_EXT_API - * @brief check wheather device rooted 1:rooted, 0:unrooted - * - * @param NULL - * - * @retval true means device is rooted - */ -bool TEE_EXT_IsDeviceRooted(void); - #ifdef __cplusplus #if __cplusplus extern "C" { diff --git a/include/TA/huawei_ext/tee_log.h b/include/TA/huawei_ext/tee_log.h index 37317ca..028fa46 100644 --- a/include/TA/huawei_ext/tee_log.h +++ b/include/TA/huawei_ext/tee_log.h @@ -29,16 +29,16 @@ #define TA_LOG_LEVEL TA_LOG_LEVEL_DEFAULT #endif -#define TAG_VERB "[verb]" -#define TAG_DEBUG "[debug]" -#define TAG_INFO "[info]" -#define TAG_WARN "[warn]" -#define TAG_ERROR "[error]" +#define TAG_VERB "[VERB]" +#define TAG_DEBUG "[DEBUG]" +#define TAG_INFO "[INFO]" +#define TAG_WARN "[WARN]" +#define TAG_ERROR "[ERROR]" -#define DEBUG_TAG "[debug]" -#define INFO_TAG "[info]" -#define WARNING_TAG "[warning]" -#define ERROR_TAG "[error]" +#define DEBUG_TAG "[DEBUG]" +#define INFO_TAG "[INFO]" +#define WARNING_TAG "[WARN]" +#define ERROR_TAG "[ERROR]" typedef enum { LOG_LEVEL_ERROR = 0, LOG_LEVEL_WARN = 1, @@ -211,9 +211,9 @@ in release version, users have to modify the level by compile #define ta_error(fmt, args...) uart_printf_func("%s: " fmt " ", ERROR_TAG, ##args) /* Log level for SLogx */ -#define TRACE_S "[Trace]" -#define WARNING_S "[Warning]" -#define ERROR_S "[Error]" +#define TRACE_S "[TRACE]" +#define WARNING_S "[WARN]" +#define ERROR_S "[ERROR]" #define TA_SLOG_LEVEL_ERROR 0 #define TA_SLOG_LEVEL_WARNING 1 diff --git a/include/TA/tee_arith_api.h b/include/TA/tee_arith_api.h index 313359a..aef47b8 100755 --- a/include/TA/tee_arith_api.h +++ b/include/TA/tee_arith_api.h @@ -284,8 +284,8 @@ void TEE_BigIntSquare(TEE_BigInt *dest, const TEE_BigInt *op); * computes dest_r and dest_q such that op1 = dest_q * op2 + dest_r * * @param dest_q [OUT] Pointer to a TEE_BigInt to store the quotient - * @param dest_r [IN] Pointer to a TEE_BigInt to store the remainder - * @param op1 [OUT] Pointer to the first operand, the dividend + * @param dest_r [OUT] Pointer to a TEE_BigInt to store the remainder + * @param op1 [IN] Pointer to the first operand, the dividend * @param op2 [IN] Pointer to the second operand, the divisor * * @return #TEE_SUCCESS operation success diff --git a/include/TA/tee_crypto_api.h b/include/TA/tee_crypto_api.h index 5abedf2..0908f83 100644 --- a/include/TA/tee_crypto_api.h +++ b/include/TA/tee_crypto_api.h @@ -18,10 +18,6 @@ #include #include -#ifndef NULL -#define NULL ((void *)0) -#endif - #define TEE_MAX_KEY_SIZE_IN_BITS (1024 * 8) #define SW_RSA_KEYLEN 1024 #define TEE_DH_MAX_SIZE_OF_OTHER_INFO 64 /* bytes */ @@ -35,6 +31,7 @@ enum __TEE_Operation_Constants { TEE_OPERATION_ASYMMETRIC_CIPHER = 6, TEE_OPERATION_ASYMMETRIC_SIGNATURE = 7, TEE_OPERATION_KEY_DERIVATION = 8, + TEE_OPERATION_KDF_KEY_DERIVATION = 9, }; enum __tee_crypto_algorithm_id { @@ -103,6 +100,7 @@ enum __tee_crypto_algorithm_id { TEE_ALG_HMAC_SM3 = 0x30000007, TEE_ALG_AES_ECB_PKCS5 = 0x10000020, TEE_ALG_AES_CBC_PKCS5 = 0x10000220, + TEE_ALG_AES_CBC_ISO_PADDING = 0x10000330, TEE_ALG_ECDSA_SHA1 = 0x70001042, TEE_ALG_ECDSA_SHA224 = 0x70002042, TEE_ALG_ECDSA_SHA256 = 0x70003042, @@ -136,6 +134,12 @@ enum __tee_crypto_algorithm_id { TEE_ALG_SM4_OFB = 0x10000514, TEE_ALG_AES_OFB = 0x10000510, TEE_ALG_SM4_GCM = 0xF0000005, + TEE_ALG_PBKDF2_HMAC_SHA1_DERIVE_KEY = 0x800020C2, + TEE_ALG_PBKDF2_HMAC_SHA256_DERIVE_KEY = 0x800040C2, + TEE_ALG_PBKDF2_HMAC_SHA384_DERIVE_KEY = 0x800050C2, + TEE_ALG_PBKDF2_HMAC_SHA512_DERIVE_KEY = 0x800060C2, + TEE_ALG_HKDF = 0x80000047, + TEE_ALG_PRF = 0xF0000006, }; typedef enum __tee_crypto_algorithm_id tee_crypto_algorithm_id; @@ -272,6 +276,8 @@ struct __TEE_OperationHandle { uint32_t dh_hash_mode; /* #TEE_DH_HASH_Mode */ uint32_t dh_derive_func; /* #TEE_DH_DerivFuncMode */ uint32_t dh_op_mode; /* #TEE_DH_OpMode_t */ + void *dh_prime; + uint32_t dh_prime_size; /* end of DH */ pthread_mutex_t operation_lock; void *hal_info; @@ -316,7 +322,7 @@ typedef struct __TEE_ObjectHandle TEE_ObjectHandleVar; * * @return TEE_SUCCESS succss * @return TEE_ERROR_OUT_OF_MEMORY #TEE_OperationHandle malloc failed - * @return TEE_ERROR_NOT_SUPPORTE #TEE_CRYPTO_ALGORITHM_ID not support + * @return TEE_ERROR_NOT_SUPPORTE #TEE_CRYPTO_ALGORITHM_ID not support or max key size is out of range * @return TEE_ERROR_GENERIC other failed */ TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation, uint32_t algorithm, uint32_t mode, @@ -333,7 +339,7 @@ void TEE_FreeOperation(TEE_OperationHandle operation); /* * get Operation Info * - * @param operation [IN/OUT] #TEE_OperationHandle + * @param operation [IN] #TEE_OperationHandle * @param operationInfo [IN/OUT] #TEE_OperationInfo * * @return void @@ -353,7 +359,7 @@ void TEE_ResetOperation(TEE_OperationHandle operation); * set operation key * * @param operation [IN/OUT] #TEE_OperationHandle - * @param key [IN/OUT] #TEE_ObjectHandle + * @param key [IN] #TEE_ObjectHandle * * @return TEE_SUCCESS succss * @return TEE_ERROR_BAD_PARAMETERS the params is invalid @@ -365,8 +371,8 @@ TEE_Result TEE_SetOperationKey(TEE_OperationHandle operation, const TEE_ObjectHa * set operation key1 and key2 * * @param operation [IN/OUT] #TEE_OperationHandle - * @param key1 [IN/OUT] #TEE_ObjectHandle - * @param key2 [IN/OUT] #TEE_ObjectHandle + * @param key1 [IN] #TEE_ObjectHandle + * @param key2 [IN] #TEE_ObjectHandle * * @return TEE_SUCCESS succss * @return TEE_ERROR_BAD_PARAMETERS the params is invalid @@ -377,7 +383,7 @@ TEE_Result TEE_SetOperationKey2(TEE_OperationHandle operation, const TEE_ObjectH * copy src operation to dest operation * * @param dst_operation [IN/OUT] #TEE_OperationHandle - * @param src_operation [IN/OUT] #TEE_OperationHandle + * @param src_operation [IN] #TEE_OperationHandle * * @return void */ @@ -611,8 +617,8 @@ TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle operation, void *srcData, size * @param srcLen [IN] the length of src data * @param destData [OUT] the dest data * @param destLen [OUT] the length of dest data - * @param tag [OUT] the tag buffer - * @param tagLen [OUT] the length of tag buffer + * @param tag [IN] the tag buffer + * @param tagLen [IN] the length of tag buffer * * @return TEE_SUCCESS succss * @return TEE_ERROR_MAC_INVALID the tag is invalid @@ -683,8 +689,8 @@ TEE_Result TEE_AsymmetricSignDigest(TEE_OperationHandle operation, const TEE_Att * @param paramCount [IN] the count of params * @param digest [IN] the digest data * @param digestLen [IN] the length of digest data - * @param signature [OUT] the signature data - * @param signatureLen [OUT] the length of signature data + * @param signature [IN] the signature data + * @param signatureLen [IN] the length of signature data * * @return TEE_SUCCESS succss * @return TEE_ERROR_BAD_PARAMETERS the params is invalid @@ -700,7 +706,7 @@ TEE_Result TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation, const TEE_A * * @param operation [IN/OUT] #TEE_OperationHandle * @param operationInfoMultiple [IN/OUT] #TEE_OperationInfoMultiple - * @param operationSize [IN/OUT] the size of operation handle + * @param operationSize [IN] the size of operation handle * * @return TEE_SUCCESS succss * @return TEE_ERROR_BAD_PARAMETERS the params is invalid diff --git a/include/TA/tee_defines.h b/include/TA/tee_defines.h index 6b24ff2..ca5cdc2 100755 --- a/include/TA/tee_defines.h +++ b/include/TA/tee_defines.h @@ -149,6 +149,13 @@ enum TEE_ObjectAttribute { TEE_ATTR_PBKDF2_HMAC_PASSWORD = 0xD0000133, TEE_ATTR_PBKDF2_HMAC_SALT = 0xD0000134, TEE_ATTR_PBKDF2_HMAC_DIGEST = 0xF0000135, + TEE_ATTR_PRF_LABEL = 0xD0000136, + TEE_ATTR_PRF_SEED = 0xD0000137, + TEE_ATTR_PRF_HASH_ALGORITHM = 0xF0000138, + TEE_ATTR_HKDF_SALT = 0xD0000946, + TEE_ATTR_HKDF_INFO = 0xD0000A46, + TEE_ATTR_HKDF_HASH_ALGORITHM = 0xF0000B46, + TEE_ATTR_KDF_KEY_SIZE = 0xF0000C46, }; enum TEE_ObjectType { @@ -187,6 +194,8 @@ enum TEE_ObjectType { TEE_TYPE_SM4 = 0xA0000014, TEE_TYPE_SIP_HASH = 0xF0000002, TEE_TYPE_PBKDF2_HMAC = 0xF0000004, + TEE_TYPE_HKDF = 0xA000004A, + TEE_TYPE_PRF = 0xF0000005, TEE_TYPE_CORRUPTED_OBJECT = 0xA00000BE, }; @@ -235,6 +244,9 @@ enum TEE_Result_Value { TEE_ERROR_STORAGE_EROFS = 0x80001007, /* stroage section is read only */ TEE_ERROR_STORAGE_PATH_WRONG = 0x8000100A, /* File path error */ TEE_ERROR_MSG_QUEUE_OVERFLOW = 0x8000100B, /* sevice msg queue overflow */ + TEE_ERROR_SUBTHREAD_ACCESS = 0x8000100C, /* The subthread created by TA cannot access the service */ + TEE_ERROR_ORIGIN_PARTITION_INACTIVE = 0x8000100D, /* Enable backup feature, original partition is inactive */ + TEE_ERROR_BACKUP_PARTITION_INACTIVE = 0x8000100E, /* Enable backup feature, backup partition is inactive */ TEE_ERROR_CORRUPT_OBJECT = 0xF0100001, /* file object has been damaged */ TEE_ERROR_STORAGE_NOT_AVAILABLE = 0xF0100003, /* storage section is unavailable */ TEE_ERROR_CIPHERTEXT_INVALID = 0xF0100006, /* cipher text is incorrect */ @@ -316,7 +328,8 @@ enum TEE_Result_Value { TEE_ERROR_ANTIROOT_INVOKE_ERROR = 0xFFFF9111, /* AntiRoot ERROR during invokecmd */ TEE_ERROR_AUDIT_FAIL = 0xFFFF9112, /* audit failed */ TEE_FAIL2 = 0xFFFF9113, /* unused */ - TEE_ERROR_IPC_OVERFLOW = 0xFFFF9114 /* IPC Channel overflow error */ + TEE_ERROR_IPC_OVERFLOW = 0xFFFF9114, /* IPC Channel overflow error */ + TEE_ERROR_APM = 0xFFFF9115, /* APM error */ }; /* diff --git a/include/TA/tee_object_api.h b/include/TA/tee_object_api.h index a62f68f..03f80bf 100644 --- a/include/TA/tee_object_api.h +++ b/include/TA/tee_object_api.h @@ -205,7 +205,7 @@ void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID, uint32_t * which is equivalent to copying the TEE_Attribute of srcobject to destobject * * @attention The TEE_Attribute type and number of the two objects must match - * @param destObject [IN] The uninitialized TEE_ObjectHandle to be assigned + * @param destObject [OUT] The uninitialized TEE_ObjectHandle to be assigned * @param srcObject [IN] The initialized TEE_ObjectHandle is used to assign a value to another object * * @return void @@ -215,7 +215,7 @@ void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject, TEE_ObjectHandle srcO /* * This function generates a random key or key-pair and assigns it to the transient object * - * @param object [IN] Transient object, used to store the generated key + * @param object [IN/OUT] Transient object, used to store the generated key * @param keySize [IN] The bytes of the required key * @param params [IN] Parameters required for key generation * @param paramCount [IN] The number of parameters required to generate the key @@ -258,7 +258,7 @@ TEE_Result TEE_GetObjectInfo1(TEE_ObjectHandle object, TEE_ObjectInfo *objectInf * which is equivalent to copying the TEE_Attribute of srcobject to destobject * * @attention The TEE_Attribute type and number of the two objects must match - * @param destObject [IN] The uninitialized TEE_ObjectHandle to be assigned + * @param destObject [IN/OUT] The uninitialized TEE_ObjectHandle to be assigned * @param srcObject [IN] The initialized TEE_ObjectHandle is used to assign a value to another object * * @return TEE_SUCCESS Indicates that the function was executed successfully @@ -275,7 +275,7 @@ TEE_Result TEE_CopyObjectAttributes1(TEE_ObjectHandle destObject, TEE_ObjectHand * * @attention The newly created object will contain all Usage_Constants, and the usage flag can * only be cleared, not set - * @param object [IN] Need to restrict TEE_ObjectHandle + * @param object [IN/OUT] Need to restrict TEE_ObjectHandle * @param objectUsage [IN] ObjectUsage users want to change * * @return TEE_SUCCESS Indicates that the function was executed successfully diff --git a/include/TA/tee_property_api.h b/include/TA/tee_property_api.h index 2d8b567..a368adc 100644 --- a/include/TA/tee_property_api.h +++ b/include/TA/tee_property_api.h @@ -70,7 +70,6 @@ TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator, const ch */ TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator, const char *name, uint32_t *value); -#if defined(API_LEVEL) && defined(API_LEVEL1_2) && (API_LEVEL >= API_LEVEL1_2) /* * retrieves a single property in a property set and converts its value to a 64-bit unsigned integer * @@ -82,7 +81,6 @@ TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator, const cha * @return TEE_ERROR_ITEM_NOT_FOUND cannot find target property */ TEE_Result TEE_GetPropertyAsU64(TEE_PropSetHandle propsetOrEnumerator, const char *name, uint64_t *value); -#endif // API_LEVEL /* * retrieves an individual property and converts its value into a binary block diff --git a/include/TA/tee_trusted_storage_api.h b/include/TA/tee_trusted_storage_api.h index cfe7554..a3d3396 100644 --- a/include/TA/tee_trusted_storage_api.h +++ b/include/TA/tee_trusted_storage_api.h @@ -78,12 +78,14 @@ enum Data_Flag_Constants { TEE_DATA_FLAG_CREATE = 0x00000200, /* * Protect an existing file with the same name. If the file with the same name does not exist, - * create a new data file; if the file with the same name exists, an error will be reported + * create a new data file; if the file with the same name exists, an error will be reported. + * Used in GP v1.1, deprecated in GP v1.2 */ TEE_DATA_FLAG_EXCLUSIVE = 0x00000400, /* * Protect an existing file with the same name. If the file with the same name does not exist, - * create a new data file; if the file with the same name exists, an error will be reported + * create a new data file; if the file with the same name exists, an error will be reported. + * Used in GP v1.2 */ TEE_DATA_FLAG_OVERWRITE = 0x00000400, /* @@ -119,7 +121,7 @@ enum Data_Flag_Constants { * @return TEE_ERROR_OUT_OF_MEMORY Insufficient memory to complete the operation * @return TEE_ERROR_STORAGE_NO_SPACE There is not enough space to create the object */ -TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *ojbectID, size_t objectIDLen, uint32_t flags, +TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *objectID, size_t objectIDLen, uint32_t flags, TEE_ObjectHandle attributes, const void *initialData, size_t initialDataLen, TEE_ObjectHandle *object); @@ -140,7 +142,7 @@ TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *ojbectID, * @return TEE_ERROR_ACCESS_CONFLICT Access conflict * @return TEE_ERROR_OUT_OF_MEMORY Insufficient memory to complete the operation */ -TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *ojbectID, size_t objectIDLen, uint32_t flags, +TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *objectID, size_t objectIDLen, uint32_t flags, TEE_ObjectHandle *object); /* @@ -155,7 +157,7 @@ TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *ojbectID, si * @return TEE_SUCCESS Indicates that the function was executed successfully * @return TEE_ERROR_OUT_OF_MEMORY Insufficient memory to complete the operation */ -TEE_Result TEE_ReadObjectData(TEE_ObjectHandle ojbect, void *buffer, size_t size, uint32_t *count); +TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer, size_t size, uint32_t *count); /* * Write size bytes of data from the buffer to the data stream of the object. @@ -169,7 +171,7 @@ TEE_Result TEE_ReadObjectData(TEE_ObjectHandle ojbect, void *buffer, size_t size * @return TEE_ERROR_OUT_OF_MEMORY Insufficient memory to complete the operation * @return TEE_ERROR_STORAGE_NO_SPACE There is not enough space to perform the operation */ -TEE_Result TEE_WriteObjectData(TEE_ObjectHandle ojbect, const void *buffer, size_t size); +TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void *buffer, size_t size); /* * This function changes the size of the data stream. If the size is smaller than the size of diff --git a/test/TA/helloworld/Makefile b/test/TA/helloworld/Makefile index 1a659b2..99a80f9 100644 --- a/test/TA/helloworld/Makefile +++ b/test/TA/helloworld/Makefile @@ -25,4 +25,4 @@ src/%.o: ./src/%.c $(CC) $(CFLAGS) $(INCLUDEDIR) -c $< -o $@ clean: - rm -f $(COBJS) *.so *.sec + rm -f $(COBJS) *.so *.sec hash_*.txt diff --git a/thirdparty/open_source/musl/libc/hm/thread.h b/thirdparty/open_source/musl/libc/hm/thread.h index 2928944..b80b576 100644 --- a/thirdparty/open_source/musl/libc/hm/thread.h +++ b/thirdparty/open_source/musl/libc/hm/thread.h @@ -23,7 +23,7 @@ // Hongmeng thread int set_thread_priority(cref_t thread, int priority); -unsigned long thread_tid(); +unsigned long thread_tid(void); int __libc_pthread_reinit(void); #endif diff --git a/thirdparty/open_source/musl/libc/sys/scs_security.h b/thirdparty/open_source/musl/libc/sys/scs_security.h new file mode 100644 index 0000000..f212e8b --- /dev/null +++ b/thirdparty/open_source/musl/libc/sys/scs_security.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020 ~ 2020. All rights reserved. + * Description: Interface declaration for scs + * Author: Huawei OS Kernel Lab + * Create: Tur Fri 9 18:36:09 2023 + */ + +#if defined(CONFIG_ARM64_SCS) && defined(__aarch64__) +bool dl_is_scs_open(void *handle); +int pthread_attr_enable_shadow_call_stack(pthread_attr_t *a); +#endif diff --git a/thirdparty/open_source/musl/libc/sys/sysinfo.h b/thirdparty/open_source/musl/libc/sys/sysinfo.h new file mode 100644 index 0000000..9b095ff --- /dev/null +++ b/thirdparty/open_source/musl/libc/sys/sysinfo.h @@ -0,0 +1,38 @@ +#ifndef _SYS_SYSINFO_H +#define _SYS_SYSINFO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _LINUX_KERNEL_H +#define SI_LOAD_SHIFT 16 + +struct sysinfo { + unsigned long uptime; + unsigned long loads[3]; + unsigned long totalram; + unsigned long freeram; + unsigned long sharedram; + unsigned long bufferram; + unsigned long totalswap; + unsigned long freeswap; + unsigned short procs, pad; + unsigned long totalhigh; + unsigned long freehigh; + unsigned mem_unit; + char __reserved[256]; +}; +#endif + +int sysinfo (struct sysinfo *); +int get_nprocs_conf (void); +int get_nprocs (void); +long get_phys_pages (void); +long get_avphys_pages (void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/ca_auth_hash_tools/ReadMe.txt b/tools/ca_auth_hash_tools/ReadMe.txt new file mode 100644 index 0000000..5ceec43 --- /dev/null +++ b/tools/ca_auth_hash_tools/ReadMe.txt @@ -0,0 +1,23 @@ +1. This is a calcuating ca authentication caller information hash tool. + +2. The TA developers can use this tool to calculate ca caller hash values +when calling "AddCaller_CA" interface to add caller authentication information for CA. + +3. usage: +step 1: configure ca_caller_info.xml file; +step 2: execute this command: python3 calc_ca_caller_hash.py. + +4. Reference hash value: +("/vendor/bin/teec_hello", 0): +0xca 0x9f 0x5e 0xd7 0x6d 0x7 0xd 0x66 0xe7 0xb2 0xab 0xb3 0x55 0xfc 0xb0 0xbf +0xc8 0x16 0x52 0x37 0x5f 0xfe 0x99 0xfc 0x34 0x43 0xf6 0x5f 0xc 0x70 0x44 0x48 + +("/vendor/bin/teec_hello", "root"): +0x29 0x89 0x3c 0x7f 0x92 0xfd 0xce 0x8e 0xd9 0x66 0xfc 0xa0 0x10 0xa0 0xe2 0xa3 +0x42 0x31 0x7d 0x65 0x36 0x48 0x38 0x86 0xf1 0x8 0x1b 0x8 0x12 0xc2 0x4c 0x9b + +("com.example.myapplicationohdemo", + "6f85f3ad5fa01dfcddd4b2f23815f47fc03a68fbe99297be20bd0e114b7e8c54", + "650769812a97c80a3751f015e7b6069492c0fe8de375abe8cdf9188c9c0d3851"): +0x5c 0x86 0x46 0xb2 0x11 0xb 0x92 0xa0 0x5a 0x12 0x90 0x8c 0x6a 0x98 0xbe 0xf2 +0x10 0x6e 0x65 0x20 0x7b 0xa1 0xc5 0x3e 0x55 0x34 0xac 0x36 0x5a 0xe2 0xf5 0xe9 diff --git a/tools/ca_auth_hash_tools/ca_caller_info.xml b/tools/ca_auth_hash_tools/ca_caller_info.xml new file mode 100644 index 0000000..cd57661 --- /dev/null +++ b/tools/ca_auth_hash_tools/ca_caller_info.xml @@ -0,0 +1,15 @@ + + + diff --git a/tools/ca_auth_hash_tools/calc_ca_caller_hash.py b/tools/ca_auth_hash_tools/calc_ca_caller_hash.py new file mode 100644 index 0000000..13c06c9 --- /dev/null +++ b/tools/ca_auth_hash_tools/calc_ca_caller_hash.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python3 +# coding=utf-8 +#---------------------------------------------------------------------------- +# Copyright @ Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. +# calc ca caller hash for AddCaller_CA +#---------------------------------------------------------------------------- + +import hashlib +from ctypes import sizeof +from ctypes import c_uint32 +from ctypes import create_string_buffer +from ctypes import memmove +from ctypes import byref +import binascii +import struct +import logging +import os +from defusedxml import ElementTree as ET + +logging.basicConfig(level=logging.INFO, + format='%(asctime)s line:%(lineno)d %(levelname)s:%(name)s:%(message)s', + datefmt='%H:%M:%S' + ) + +MAX_PKGNAME_LEN = 256 +MAX_USERNAME_LEN = 256 +MAX_MODULUS_LEN = 1024 +MAX_PUB_EXP_LEN = 256 + + +def print_hash(byte_buf): + """ print caller hash """ + buf = [hex(int(i)) for i in byte_buf] + output = " ".join(buf) + logging.info("caller hash: %s", output) + + +def check_native_ca_item(item): + """ check native ca item vaule """ + if item.tag != "item" or len(item.attrib) != 2: + raise RuntimeError("invalid item attrib", item.tag, item.attrib, len(item.attrib)) + + +def check_apk_hap_ca_item(item): + """ check apk_hap item vaule """ + if item.tag != "item" or len(item.attrib) != 3: + raise RuntimeError("invalid item attrib", item.tag, item.attrib, len(item.attrib)) + + +def check_pkgname_type(value): + """ check pkgname type """ + if len(value) == 0 or len(value) > MAX_PKGNAME_LEN: + raise RuntimeError("invalid pkgname, the pkgname length must be in range (0, {}]".format(MAX_PKGNAME_LEN), \ + value, len(value)) + + +def check_uid_type(value): + """ check uid type """ + if int(value, 10) > 0xffffffff or int(value, 10) < 0: + raise RuntimeError("invalid uid, the uid value must be in [0, 0xffffffff]", value) + + +def check_username_type(value): + """ check username type """ + if len(value) == 0 or len(value) > MAX_USERNAME_LEN: + raise RuntimeError("invalid username, the username length must be in range (0, {}]".format(MAX_USERNAME_LEN), \ + value, len(value)) + + +def check_module_type(value): + """ check module type """ + if len(value) == 0 or (len(value) / 2) > MAX_MODULUS_LEN: + raise RuntimeError("invalid module, the module length must be in range (0, {}]".format(MAX_MODULUS_LEN * 2), \ + value, len(value)) + + +def check_exponent_type(value): + """ check exponent type """ + if len(value) == 0 or (len(value) / 2) > MAX_PUB_EXP_LEN: + raise RuntimeError( \ + "invalid exponent, the exponent length must be in range (0, {}]".format(MAX_PUB_EXP_LEN * 2), \ + value, len(value)) + + +def calc_sha256(buf): + """ calcuate sha256 """ + hash_op = hashlib.sha256() + hash_op.update(buf) + return hash_op.digest() + + +def calc_cmdline_uid_hash(cmdline, uid): + """ calcuate cmdline||uid hash """ + c_uid = c_uint32(uid) + c_str = create_string_buffer(cmdline.encode('utf-8'), len(cmdline) + sizeof(c_uid)) + memmove(byref(c_str, len(c_str.value)), byref(c_uid), sizeof(c_uid)) + return calc_sha256(c_str) + + +def calc_cmdline_username_hash(cmdline, username): + """ calcuate cmdline||username hash """ + c_str = create_string_buffer((cmdline + username).encode('utf-8'), len(cmdline) + MAX_USERNAME_LEN) + return calc_sha256(c_str) + + +def calc_apk_caller_hash(apk_pkg_name, apk_modulus, apk_public_exponent): + """ calcuate pkg_name||modulus||exponent hash """ + hex_modulus = binascii.a2b_hex(apk_modulus) + hex_exponent = binascii.a2b_hex(apk_public_exponent) + pub_key_format = "{}s{}s".format(len(hex_modulus), len(hex_exponent)) + hex_pub_key = struct.pack(pub_key_format, hex_modulus, hex_exponent) + c_str = create_string_buffer((apk_pkg_name).encode('utf-8'), \ + len(apk_pkg_name) + len(hex_pub_key)) + memmove(byref(c_str, len(c_str.value)), bytes(hex_pub_key), len(hex_pub_key)) + return calc_sha256(c_str) + + +def handle_cmdline_uid_item_hash(item): + """ handle cmdline_uid_item hash """ + cmdline = "" + uid = 0 + for attr in item.attrib: + value = item.attrib[attr] + if attr == "cmdline": + check_pkgname_type(value) + cmdline = value + elif attr == "uid": + check_uid_type(value) + uid = int(value, 10) + else: + raise RuntimeError("invalid item attr", attr) + caller_hash = calc_cmdline_uid_hash(cmdline, uid) + logging.info("cmdline: %s, uid: %s", cmdline, uid) + print_hash(caller_hash) + + +def handle_cmdline_uid(child): + """ handle cmdline_uid """ + for item in child: + check_native_ca_item(item) + handle_cmdline_uid_item_hash(item) + + +def handle_cmdline_username_item_hash(item): + """handle cmdline_username_item hash """ + cmdline = "" + username = "" + for attr in item.attrib: + value = item.attrib[attr] + if attr == "cmdline": + check_pkgname_type(value) + cmdline = value + elif attr == "username": + check_username_type(value) + username = value + else: + raise RuntimeError("invalid item attr", attr) + caller_hash = calc_cmdline_username_hash(cmdline, username) + logging.info("cmdline: %s, username: %s", cmdline, username) + print_hash(caller_hash) + + +def handle_cmdline_username(child): + """ handle cmdline_username """ + for item in child: + check_native_ca_item(item) + handle_cmdline_username_item_hash(item) + + +def handle_apk_hap_item_hash(item): + """ handle apk_hap_item hash """ + pkg_name = "" + modulue = "" + exponent = "" + for attr in item.attrib: + value = item.attrib[attr] + if attr == "pkg_name": + check_pkgname_type(value) + pkg_name = value + elif attr == "modulue": + check_module_type(value) + modulue = value + elif attr == "exponent": + check_exponent_type(value) + exponent = value + else: + raise RuntimeError("invalid item attr", attr) + caller_hash = calc_apk_caller_hash(pkg_name, modulue, exponent) + logging.info("pkg_name: %s, module: %s, exponent: %s", pkg_name, modulue, exponent) + print_hash(caller_hash) + + +def handle_apk_hap(child): + """handle apk_hap """ + for item in child: + check_apk_hap_ca_item(item) + handle_apk_hap_item_hash(item) + + +def do_calc_caller_info_hash(ca_caller_info_root): + """ calc caller info hash """ + for child in ca_caller_info_root: + if child.tag == "cmdline_uid": + handle_cmdline_uid(child) + elif child.tag == "cmdline_username": + handle_cmdline_username(child) + elif child.tag == "apk_hap": + handle_apk_hap(child) + else: + raise RuntimeError("not support xml tag", child.tag) + + +def main(): + """ main """ + ca_caller_info_xml = "ca_caller_info.xml" + if not os.path.exists(ca_caller_info_xml): + raise RuntimeError("caller_info.xml file doesn't exist") + + tree = ET.parse(ca_caller_info_xml) + ca_caller_info_root = tree.getroot() + + # parser caller info file + do_calc_caller_info_hash(ca_caller_info_root) + + +if __name__ == "__main__": + main() -- Gitee