初始提交
This commit is contained in:
24
build/config/target_config/ws63/sign_encry/Readme.txt
Executable file
24
build/config/target_config/ws63/sign_encry/Readme.txt
Executable file
@ -0,0 +1,24 @@
|
||||
=========================================================
|
||||
<EFBFBD><EFBFBD><EFBFBD>ܼ<EFBFBD>ǩ<EFBFBD><EFBFBD><EFBFBD>./encryptandsign.sh <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><33>
|
||||
|
||||
һ<EFBFBD><EFBFBD><EFBFBD>ű<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܼ<EFBFBD>ǩ<EFBFBD>ļ<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD><C9A3><EFBFBD>д<EFBFBD><D0B4>λ<EFBFBD><CEBB>output/ws63/pktbin.zip<69><70>ota<74><61><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>output/ws63/upgrade/ota_pktbin.zip
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܼ<EFBFBD>ǩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD>all<EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ota:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
=========================================================
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>sign_encry<EFBFBD><EFBFBD>Ŀ¼<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
1)./ <20><><EFBFBD>ܼ<EFBFBD>ǩ<EFBFBD><C7A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD>еļ<D0B5><C4BC>ܼ<EFBFBD>ǩ<EFBFBD><C7A9><EFBFBD>ߡ<EFBFBD><DFA1><EFBFBD><EFBFBD>ű<F2A1A2BD><C5B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>Ŀ¼<C4BF><C2BC>
|
||||
tool_security<EFBFBD><EFBFBD> flash<73><68>Կ<EFBFBD><D4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
sign_tool_pltuni<EFBFBD><EFBFBD> ǩ<><C7A9><EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD><DCB9><EFBFBD>
|
||||
2)./config/sign<67><6E>ǩ<EFBFBD><C7A9><EFBFBD><EFBFBD>flash<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>Կ<EFBFBD><D4BF><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>
|
||||
ec_bp256_oem_root_public_key.pem Ϊ<><CEAA><EFBFBD><EFBFBD>Կ<EFBFBD><D4BF><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><D4A3><EFBFBD><EFBFBD><EFBFBD>hashֵ<68><D6B5>root_pubk.bin.hash<73><68>
|
||||
ec_bp256_oem_root_private_key.pemΪ<6D><CEAA>˽Կ<CBBD><D4BF><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ծ<EFBFBD><D4BE><EFBFBD>ǩ<EFBFBD><C7A9>flashboot.bin
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>༶<EFBFBD><EFBFBD>Կ
|
||||
3)./config/ota<74><61>fota<74><61><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><CDB9><EFBFBD><EFBFBD><EFBFBD>Կ<EFBFBD><D4BF><EFBFBD><EFBFBD>·<EFBFBD><C2B7>
|
||||
|
||||
=========================================================
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Կ (<28><><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA>Ḳ<EFBFBD><E1B8B2><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Կ)
|
||||
1.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Կ<EFBFBD><D4BF><EFBFBD><EFBFBD>
|
||||
cd ./sign_encry
|
||||
./gen_all_key.sh
|
924
build/config/target_config/ws63/sign_encry/build_ota_img.py
Executable file
924
build/config/target_config/ws63/sign_encry/build_ota_img.py
Executable file
@ -0,0 +1,924 @@
|
||||
#!/usr/bin/env python3
|
||||
# coding=utf-8
|
||||
|
||||
import argparse
|
||||
import configparser
|
||||
import os
|
||||
import re
|
||||
import hashlib
|
||||
import sys
|
||||
import subprocess
|
||||
import copy
|
||||
import struct
|
||||
import platform
|
||||
import shutil
|
||||
from ctypes import *
|
||||
|
||||
###############################Defining Basic Types###############################################
|
||||
td_char = c_char
|
||||
td_s8 = c_byte
|
||||
td_u8 = c_ubyte
|
||||
td_s16 = c_short
|
||||
td_u16 = c_ushort
|
||||
td_s32 = c_int
|
||||
td_u32 = c_uint
|
||||
|
||||
file_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
g_root = os.path.realpath(os.path.join(file_dir,))
|
||||
|
||||
class fota_key_area_data(Structure):
|
||||
pass
|
||||
|
||||
class fota_info_area_data(Structure):
|
||||
pass
|
||||
|
||||
class upg_sha256_sign(Structure):
|
||||
_fields_ = [
|
||||
("check_sum", td_u8 * 32),
|
||||
("padding", td_u8 * 224),
|
||||
]
|
||||
|
||||
class fota_image_hash_node(Structure):
|
||||
_fields_ = [
|
||||
("image_id", td_u32),
|
||||
("image_addr", td_u32),
|
||||
("image_length", td_u32),
|
||||
("image_hash", td_u8 * 32),
|
||||
]
|
||||
|
||||
class fota_image_head(Structure):
|
||||
_fields_ = [
|
||||
("header_magic", td_u32),
|
||||
("image_id", td_u32),
|
||||
("image_offset", td_u32),
|
||||
("image_len", td_u32),
|
||||
("image_hash", td_u8 * 32),
|
||||
("old_image_len", td_u32),
|
||||
("old_image_hash", td_u8 * 32),
|
||||
("new_image_len", td_u32),
|
||||
("version_ext", td_u32),
|
||||
("version_mask", td_u32),
|
||||
("decompress_flag", td_u32),
|
||||
("re_enc_flag", td_u32),
|
||||
("root_key_type", td_u32),
|
||||
("enc_pk_l1", td_u8 * 16),
|
||||
("enc_pk_l2", td_u8 * 16),
|
||||
("iv", td_u8 * 16),
|
||||
("padding", td_u8 * 4),
|
||||
]
|
||||
|
||||
class image_key_area(Structure):
|
||||
_fields_ = [
|
||||
("image_id", td_u32),
|
||||
("structure_version", td_u32),
|
||||
("structure_length", td_u32),
|
||||
("signature_length", td_u32),
|
||||
("key_owner_id", td_u32),
|
||||
("key_id", td_u32),
|
||||
("key_alg", td_u32),
|
||||
("ecc_curve_type", td_u32),
|
||||
("key_length", td_u32),
|
||||
("key_version_ext", td_u32),
|
||||
("mask_key_version_ext", td_u32),
|
||||
("msid_ext", td_u32),
|
||||
("mask_msid_ext", td_u32),
|
||||
("maintenance_mode", td_u32),
|
||||
("die_id", td_u8 * 16),
|
||||
("code_info_addr", td_u32),
|
||||
("reserved", td_u8 * 52),
|
||||
("ext_pulic_key_area", td_u8 * 64),
|
||||
("sig_key_area", td_u8 * 64),
|
||||
]
|
||||
|
||||
class image_code_area(Structure):
|
||||
_fields_ = [
|
||||
("image_id", td_u32),
|
||||
("structure_version", td_u32),
|
||||
("structure_length", td_u32),
|
||||
("signature_length", td_u32),
|
||||
("version_ext", td_u32),
|
||||
("mask_version_ext", td_u32),
|
||||
("msid_ext", td_u32),
|
||||
("mask_msid_ext", td_u32),
|
||||
("code_area_addr", td_u32),
|
||||
("code_area_len", td_u32),
|
||||
("code_area_hash", td_u8 * 32),
|
||||
("code_enc_flag", td_u32),
|
||||
("protection_key_l1", td_u8 * 16),
|
||||
("protection_key_l2", td_u8 * 16),
|
||||
("iv", td_u8 * 16),
|
||||
("code_compress_flag", td_u32),
|
||||
("code_uncompress_len", td_u32),
|
||||
("text_segment_size", td_u32),
|
||||
("reserved", td_u8 * 248),
|
||||
("sig_code_info", td_u8 * 16),
|
||||
("sig_code_info_ext", td_u8 * 16),
|
||||
]
|
||||
|
||||
class imageInfo:
|
||||
def __init__(self, path):
|
||||
with open(path, 'rb') as fp:
|
||||
image_bin = fp.read()
|
||||
key_ver = image_bin[36:40]
|
||||
key_mask = image_bin[40:44]
|
||||
key_area_len = sizeof(image_key_area)
|
||||
code_ver = image_bin[key_area_len + 16:key_area_len + 20]
|
||||
code_mask = image_bin[key_area_len + 20:key_area_len + 24]
|
||||
self.key_ver = struct.unpack("I", key_ver)
|
||||
self.key_mask = struct.unpack("I", key_mask)
|
||||
self.code_ver = struct.unpack("I", code_ver)
|
||||
self.code_mask = struct.unpack("I", code_mask)
|
||||
|
||||
def fota_format_init(upg_format_path):
|
||||
sys.path.append(upg_format_path)
|
||||
from fota_format_st import fota_key_area_data_fields, fota_info_area_data_fields
|
||||
fota_key_area_data._fields_ = fota_key_area_data_fields
|
||||
fota_info_area_data._fields_ = fota_info_area_data_fields
|
||||
|
||||
def hex2dec(string_num):
|
||||
return int(string_num.upper(), 16)
|
||||
|
||||
def fill_fota_key_area(cf, key_ver, key_mask):
|
||||
key_area_len = sizeof(fota_key_area_data)
|
||||
temp_offset = [0]
|
||||
temp_offset[0] = temp_offset[0] + key_area_len
|
||||
fota_key_bin_tmp = bytearray(temp_offset[0])
|
||||
fota_key_bin = fota_key_bin_tmp[0:key_area_len]
|
||||
fota_key_head = fota_key_area_data.from_buffer(fota_key_bin)
|
||||
|
||||
fota_key_head.image_id = hex2dec(cf.get('FOTA_KEY_AREA', 'ImageId'))
|
||||
fota_key_head.struct_version = hex2dec(cf.get('FOTA_KEY_AREA', 'StructVersion'))
|
||||
fota_key_head.struct_length = key_area_len
|
||||
fota_key_head.key_owner_id = int(cf.get('FOTA_KEY_AREA', 'KeyOwnerId'))
|
||||
fota_key_head.key_id = int(cf.get('FOTA_KEY_AREA', 'KeyId'))
|
||||
fota_key_head.key_alg = hex2dec(cf.get('FOTA_KEY_AREA', 'KeyAlg'))
|
||||
if (fota_key_head.key_alg == 0x2A13C856 or fota_key_head.key_alg == 0x2A13C867):
|
||||
fota_key_head.signature_length = 32
|
||||
else:
|
||||
fota_key_head.signature_length = sizeof(fota_key_head.sig_fota_key_area)
|
||||
fota_key_head.ecc_curve_type = 0
|
||||
fota_key_head.key_length = 0
|
||||
# fota_key_head.fota_key_version_ext = key_ver # Version of FOTA_External_Public_Key
|
||||
# fota_key_head.mask_fota_key_version_ext = key_mask
|
||||
fota_key_head.fota_key_version_ext = hex2dec(cf.get('FOTA_KEY_AREA', 'KeyVersion'))
|
||||
fota_key_head.mask_fota_key_version_ext = hex2dec(cf.get('FOTA_KEY_AREA', 'KeyVersionMask'))
|
||||
|
||||
fota_key_head.msid_ext = hex2dec(cf.get('FOTA_KEY_AREA', 'Msid'))
|
||||
fota_key_head.mask_msid_ext = hex2dec(cf.get('FOTA_KEY_AREA', 'MsidMask'))
|
||||
fota_key_head.maintenance_mode = 0
|
||||
# fota_key_head.die_id = 0
|
||||
fota_key_head.fota_info_addr = 0 # 相对fota key区末尾的地址,0表示key area后接fota info区
|
||||
# 剩下3个:预留区、公钥、签名由签名工具填充
|
||||
return key_area_len, fota_key_bin
|
||||
|
||||
def fill_fota_info_area(cf, image_num, fota_obj):
|
||||
area_len = sizeof(fota_info_area_data)
|
||||
key_alg = hex2dec(cf.get('FOTA_KEY_AREA', 'KeyAlg'))
|
||||
temp_offset = [0]
|
||||
temp_offset[0] = temp_offset[0] + area_len
|
||||
upg_bin = bytearray(temp_offset[0])
|
||||
upg_bin = upg_bin[0:area_len]
|
||||
fota_info_head = fota_info_area_data.from_buffer(upg_bin)
|
||||
|
||||
fota_info_head.image_id = hex2dec(cf.get('FOTA_INFO_AREA', 'ImageId'))
|
||||
fota_info_head.struct_version = hex2dec(cf.get('FOTA_INFO_AREA', 'StructVersion'))
|
||||
fota_info_head.struct_length = area_len
|
||||
if (key_alg == 0x2A13C856 or key_alg == 0x2A13C867):
|
||||
fota_info_head.signature_length = 32
|
||||
else:
|
||||
fota_info_head.signature_length = sizeof(fota_info_head.sign_fota_info)
|
||||
fota_info_head.fota_version_ext = hex2dec(cf.get('FOTA_INFO_AREA', 'Version'))
|
||||
fota_info_head.mask_fota_version_ext = hex2dec(cf.get('FOTA_INFO_AREA', 'VersionMask'))
|
||||
fota_info_head.msid_ext = hex2dec(cf.get('FOTA_INFO_AREA', 'Msid'))
|
||||
fota_info_head.mask_msid_ext = hex2dec(cf.get('FOTA_INFO_AREA', 'MsidMask'))
|
||||
# fota_info_head.image_hash_table_addr = 0 # 所有镜像处理完后再计算hash
|
||||
# fota_info_head.image_hash_table_length = 0
|
||||
# fota_info_head.image_hash_table_hash = 0
|
||||
fota_info_head.image_num = image_num
|
||||
fota_info_head.hardware_id = int(cf.get('FOTA_INFO_AREA', 'HardwareID'))
|
||||
if hasattr(fota_obj, 'hardware_id') and fota_info_head.hardware_id == 0:
|
||||
fota_info_head.hardware_id = fota_obj.hardware_id
|
||||
|
||||
#fota_info_head.reserved = 0 # 预留给用户
|
||||
#fota_info_head.sign_fota_info = 0 # 签名
|
||||
|
||||
return area_len, upg_bin
|
||||
|
||||
def set_fota_info_area(fota_info_len, upg_bin, hash_table_addr, hash_table_length, hash_table_hash):
|
||||
tmp_bin = upg_bin[0:fota_info_len]
|
||||
fota_info_head = fota_info_area_data.from_buffer(tmp_bin)
|
||||
fota_info_head.image_hash_table_addr = hash_table_addr
|
||||
fota_info_head.image_hash_table_length = hash_table_length
|
||||
tmp_bin[40:72] = hash_table_hash[0:32] # 填充fota_info_head.image_hash_table_hash
|
||||
upg_bin[0:fota_info_len] = tmp_bin
|
||||
return
|
||||
|
||||
def make_sha256_unsecure_signature(content):
|
||||
# common段非安全签名
|
||||
# Non-secure signature of common field
|
||||
signature_bin = bytearray(sizeof(upg_sha256_sign))
|
||||
signature = upg_sha256_sign.from_buffer(signature_bin)
|
||||
common_head_sh = hashlib.sha256()
|
||||
common_head_sh.update(content)
|
||||
common_head_hash = common_head_sh.digest()
|
||||
signature_bin[0:sizeof(signature.check_sum)] = common_head_hash
|
||||
return signature_bin
|
||||
|
||||
def fill_fota_image_hash_node(hash_bin, image_id, image_index, tmp_hash, addr_offset, image_length):
|
||||
hash_node_size = sizeof(fota_image_hash_node)
|
||||
start_offset = image_index * hash_node_size
|
||||
tmp_hash_bin = bytearray(hash_node_size)
|
||||
fota_hash= fota_image_hash_node.from_buffer(tmp_hash_bin)
|
||||
|
||||
fota_hash.image_id = image_id
|
||||
fota_hash.image_addr = addr_offset
|
||||
fota_hash.image_length = image_length
|
||||
tmp_hash_bin[12:44] = tmp_hash[0:32]
|
||||
|
||||
hash_bin[start_offset:start_offset + hash_node_size] = tmp_hash_bin
|
||||
return
|
||||
|
||||
def lzma_compress_bin(src_file, dst_file, lzma_tool):
|
||||
# print('lzma compress tool :', lzma_tool)
|
||||
# print('lzma src file :', src_file)
|
||||
# print('lzma out file :', dst_file)
|
||||
cmd_list0 = []
|
||||
if platform.system().lower() == "linux":
|
||||
cmd_list0.append('chmod')
|
||||
cmd_list0.append('755')
|
||||
cmd_list0.append(lzma_tool)
|
||||
elif platform.system().lower() == "windows":
|
||||
cmd_list0.append('cacls')
|
||||
cmd_list0.append(lzma_tool)
|
||||
cmd_list0.append('/p everyone:f /e')
|
||||
str_cmd=' '.join(cmd_list0)
|
||||
ret = subprocess.run(str_cmd, shell=True)
|
||||
if ret.returncode != 0:
|
||||
sys.exit("chmod lzma tool failed: %s" % ret)
|
||||
|
||||
cmd_list = []
|
||||
cmd_list.append(lzma_tool)
|
||||
cmd_list.append('-d12 -lc0 -lp0 e')
|
||||
cmd_list.append(src_file)
|
||||
cmd_list.append(dst_file)
|
||||
str_cmd=' '.join(cmd_list)
|
||||
ret = subprocess.run(str_cmd, shell=True)
|
||||
if ret.returncode != 0:
|
||||
sys.exit("run lzma tool failed: %s" % ret)
|
||||
|
||||
def build_diff_cfg_file(fota_obj, basename, image_pairs, image_bin_file):
|
||||
diff_cfg_file = os.path.join(fota_obj.temp_dir, '%s_diff.cfg'%basename)
|
||||
diff_cfg_content = [
|
||||
'OldVersionFile="%s"' % image_pairs[0],
|
||||
'NewVersionFile="%s"' % image_pairs[1],
|
||||
'DiffFile="%s"' % image_bin_file
|
||||
]
|
||||
remove_file(diff_cfg_file)
|
||||
create_dirs(os.path.dirname(diff_cfg_file))
|
||||
with open(diff_cfg_file, 'w') as fp:
|
||||
fp.write('\n'.join(diff_cfg_content))
|
||||
return diff_cfg_file
|
||||
|
||||
# 解密要求16byte对齐,将lzma压缩头填充至16字节对齐:[head(13byte) + body(N byte)] -> [head(16byte) + body(N byte)]
|
||||
def fill_lzma_head(upg_lzma_file, filepath, filename):
|
||||
temp_offset3 = [0]
|
||||
dst_bin = bytearray(temp_offset3[0])
|
||||
file_sta = os.stat(upg_lzma_file)
|
||||
image_len = file_sta.st_size
|
||||
with open(upg_lzma_file, 'rb') as fp:
|
||||
src_bin= fp.read()
|
||||
head_len = 13; # lzma压缩头长度
|
||||
align_len = 16 # 16byte对齐后的lzma压缩头长度
|
||||
|
||||
dst_bin[0:head_len] = src_bin[0:head_len]
|
||||
dst_bin[head_len:align_len] = bytearray(align_len - head_len)
|
||||
dst_bin[align_len:align_len + image_len - head_len] = src_bin[head_len:image_len]
|
||||
remove_file(upg_lzma_file)
|
||||
dst_lzma_file = upg_lzma_file
|
||||
with open(dst_lzma_file, 'wb') as fp:
|
||||
fp.write(dst_bin)
|
||||
return dst_lzma_file
|
||||
|
||||
def get_image_bin_data(fota_image, image_confg_key, fota_obj):
|
||||
image_bin_file = fota_obj.input_dict.get(image_confg_key)
|
||||
fota_image.new_image_len = os.stat(image_bin_file).st_size
|
||||
(filepath, tempfilename) = os.path.split(image_bin_file)
|
||||
(filename, extension) = os.path.splitext(tempfilename)
|
||||
if fota_image.image_id == 0xCB9E063C: # NV镜像不做处理,保持原数据
|
||||
pass
|
||||
elif fota_image.decompress_flag == 0x3C7896E1: # 压缩ID
|
||||
# 制作压缩升级文件
|
||||
upg_lzma_file = os.path.join(filepath, '%s.lzma'%filename)
|
||||
lzma_compress_bin('"%s"' % image_bin_file, '"%s"' % upg_lzma_file, fota_obj.lzma_tool)
|
||||
image_bin_file = fill_lzma_head(upg_lzma_file, filepath, filename)
|
||||
elif fota_image.decompress_flag == 0x44494646: # 差分ID
|
||||
# 制作差分升级文件
|
||||
if fota_obj.diff_image_info == None:
|
||||
sys.exit("[ERROR] diff image dict is None!!!")
|
||||
image_pairs = fota_obj.diff_image_info.get(image_confg_key)
|
||||
if image_pairs == None:
|
||||
sys.exit("[ERROR] diff bin is None!!!")
|
||||
# 镜像头记录新老镜像长度
|
||||
fota_image.old_image_len = os.stat(image_pairs[0]).st_size
|
||||
fota_image.new_image_len = os.stat(image_pairs[1]).st_size
|
||||
# 制作旧镜像hash
|
||||
with open(image_pairs[0], 'rb') as fp: # file为旧镜像
|
||||
old_image_bin = fp.read()
|
||||
old_image_hash = make_sha256_unsecure_signature(old_image_bin)
|
||||
fota_image.old_image_hash[:] = old_image_hash[0:32]
|
||||
# 差分后的镜像
|
||||
image_bin_file = os.path.join(os.path.dirname(image_pairs[1]), '%s_diff.bin'%filename)
|
||||
# 差分配置文件
|
||||
diff_cfg_file = build_diff_cfg_file(fota_obj, filename, image_pairs, image_bin_file)
|
||||
cmd = ' '.join([fota_obj.upg_tool, '4', '"%s"' % diff_cfg_file])
|
||||
ret = subprocess.run(cmd, shell=True)
|
||||
if ret.returncode != 0:
|
||||
sys.exit("run diff tool failed: %d" % ret)
|
||||
with open(image_bin_file, 'rb') as fp: # 不压缩时新镜像和原镜像一致, file为原镜像
|
||||
image_bin= fp.read()
|
||||
file_stats = os.stat(image_bin_file)
|
||||
return image_bin, file_stats.st_size
|
||||
|
||||
def fill_fota_image_head(fota_image, cf, image_confg_key, start_offset, image_offset, fota_image_head_size):
|
||||
fota_image.header_magic = hex2dec(cf.get(image_confg_key, 'HeaderMagic'))
|
||||
fota_image.image_id = hex2dec(cf.get(image_confg_key, 'ImageId'))
|
||||
fota_image.image_offset = start_offset + image_offset + fota_image_head_size
|
||||
fota_image.old_image_len = 0
|
||||
fota_image.new_image_len = 0
|
||||
# fota_image.version_ext = int(''.join(map(str, info.code_ver)))
|
||||
# fota_image.version_mask = int(''.join(map(str, info.code_mask)))
|
||||
fota_image.version_ext = hex2dec(cf.get(image_confg_key, 'version_ext'))
|
||||
fota_image.version_mask = hex2dec(cf.get(image_confg_key, 'version_mask'))
|
||||
fota_image.decompress_flag = hex2dec(cf.get(image_confg_key, 'DecompressFlag'))
|
||||
fota_image.re_enc_flag = hex2dec(cf.get(image_confg_key, 'ReRncFlag'))
|
||||
fota_image.root_key_type = hex2dec(cf.get(image_confg_key, 'RootKeyType'))
|
||||
|
||||
def get_image_bin_final(image_bin, image_len):
|
||||
temp_offset1 = [0]
|
||||
image_bin_1 = bytearray(temp_offset1[0])
|
||||
image_bin_1[0:image_len] = image_bin
|
||||
tmp = image_len % 16
|
||||
|
||||
if tmp != 0: # 对镜像长度按照16B对齐
|
||||
tmp_hash_bin = bytearray(16 - tmp)
|
||||
image_bin_1[image_len:image_len + 16 - tmp] = tmp_hash_bin
|
||||
image_len = image_len + 16 - tmp
|
||||
return image_bin_1, image_len
|
||||
|
||||
def fill_fota_image_secure_head(upg_bin, fota_image, cf, image_confg_key, image_bin):
|
||||
tmp_hash = make_sha256_unsecure_signature(image_bin)
|
||||
fota_image.image_hash[0:32] = tmp_hash[0:32] # 填充fota_image.image_hash
|
||||
# 填充加密字段
|
||||
ReRncFlag = cf.get(image_confg_key, 'ReRncFlag')
|
||||
if ReRncFlag == "0x3C7896E1":
|
||||
fota_image_head_size = sizeof(fota_image_head)
|
||||
if cf.get(image_confg_key, 'ProtectionKeyL1') != "":
|
||||
data_byte1 = bytes.fromhex(cf.get(image_confg_key, 'ProtectionKeyL1'))
|
||||
fota_image.enc_pk_l1[0:16] = data_byte1
|
||||
if cf.get(image_confg_key, 'ProtectionKeyL2') != "":
|
||||
data_byte2 = bytes.fromhex(cf.get(image_confg_key, 'ProtectionKeyL2'))
|
||||
fota_image.enc_pk_l2[0:16] = data_byte2
|
||||
if cf.get(image_confg_key, 'Iv') != "":
|
||||
data_byte3 = bytes.fromhex(cf.get(image_confg_key, 'Iv'))
|
||||
fota_image.iv[0:16] = data_byte3
|
||||
|
||||
def create_encry_cfg(fota_obj, upg_align_file, upg_encry_file):
|
||||
remove_file(fota_obj.encry_conf_file)
|
||||
create_dirs(os.path.dirname(fota_obj.encry_conf_file))
|
||||
# 从基础文件中读取SIGN_CFG段,并写入到加密配置文件
|
||||
with open(fota_obj.encry_conf_file, 'w') as pro_file:
|
||||
for item in fota_obj.base_cfg.items("SIGN_CFG"):
|
||||
if item[0] == 'UpgImagePath':
|
||||
pro_file.write('SrcFile="%s"\n'%upg_align_file)
|
||||
elif item[0] == 'UpgSignedImagePath':
|
||||
pro_file.write('DstFile="%s"\n'%upg_encry_file)
|
||||
elif item[0] == 'SignSuite':
|
||||
pro_file.write('SignSuite=%s\n'%item[1])
|
||||
for item in fota_obj.base_cfg.items("application"):
|
||||
if item[0] == 'PlainKey':
|
||||
pro_file.write('PlainKey=%s\n'%fota_obj.base_cfg.get('application', 'PlainKey'))
|
||||
if item[0] == 'Iv':
|
||||
pro_file.write('Iv=%s\n'%fota_obj.base_cfg.get('application', 'Iv'))
|
||||
|
||||
def encry_ota_image(cf, image_confg_key, image_bin_1, fota_obj):
|
||||
image_bin_file = fota_obj.input_dict.get(image_confg_key)
|
||||
(filepath, tempfilename) = os.path.split(image_bin_file)
|
||||
(filename, extension) = os.path.splitext(tempfilename)
|
||||
|
||||
upg_align_file = os.path.join(filepath, '%s.lzma.align'%filename) # 压缩并16字节对齐的文件
|
||||
upg_encry_file = os.path.join(filepath, '%s.lzma.encry'%filename) # 加密文件
|
||||
with open(upg_align_file, 'wb+') as fp:
|
||||
fp.write(image_bin_1)
|
||||
|
||||
create_encry_cfg(fota_obj, upg_align_file, upg_encry_file)
|
||||
cmd = ' '.join([fota_obj.upg_tool, '5', '"%s"' % fota_obj.encry_conf_file])
|
||||
subprocess.run(cmd, shell=True)
|
||||
with open(upg_encry_file, 'rb') as fp:
|
||||
image_bin_1= fp.read()
|
||||
return image_bin_1
|
||||
|
||||
def fill_fota_image(cf, image_confg_key, all_image_bin, fota_obj, start_offset, image_offset):
|
||||
# 根据对应核的配置填充升级镜像头
|
||||
fota_image_head_size = sizeof(fota_image_head)
|
||||
upg_bin = bytearray(fota_image_head_size)
|
||||
fota_image = fota_image_head.from_buffer(upg_bin)
|
||||
fill_fota_image_head(fota_image, cf, image_confg_key, start_offset, image_offset, fota_image_head_size)
|
||||
|
||||
# 根据升级文件方式标志,将当前镜像处理获得新镜像(压缩、差分、原镜像三者之一)
|
||||
image_bin, image_len= get_image_bin_data(fota_image, image_confg_key, fota_obj)
|
||||
|
||||
# 最终的镜像本体, 将镜像数据做对齐处理
|
||||
image_bin_1, image_bin_1_len = get_image_bin_final(image_bin, image_len)
|
||||
fota_image.image_len = image_bin_1_len
|
||||
|
||||
# 加密
|
||||
ReRncFlag = cf.get(image_confg_key, 'ReRncFlag')
|
||||
if ReRncFlag == "0x3C7896E1":
|
||||
image_bin_1 = encry_ota_image(cf, image_confg_key, image_bin_1, fota_obj)
|
||||
|
||||
# 头部安全填充
|
||||
fill_fota_image_secure_head(upg_bin, fota_image, cf, image_confg_key, image_bin_1)
|
||||
|
||||
# 组合镜像
|
||||
# 1. 头部填充
|
||||
head_end = start_offset + fota_image_head_size
|
||||
all_image_bin[start_offset:head_end] = upg_bin
|
||||
|
||||
# 2. 镜像本体填充
|
||||
img_end = head_end + image_bin_1_len
|
||||
all_image_bin[head_end:img_end] = image_bin_1
|
||||
return fota_image_head_size + image_bin_1_len
|
||||
|
||||
def make_upg(fota_obj):
|
||||
cf = fota_obj.base_cfg
|
||||
temp_offset = [0]
|
||||
upg_bin = bytearray(temp_offset[0])
|
||||
image_num = len(fota_obj.input_dict)
|
||||
|
||||
# FOTA Key Area 填充
|
||||
# version字段暂来自配置文件,因此key area填充放到最前面
|
||||
fota_key_len, fota_key_bin_buff = fill_fota_key_area(cf, 0, 0)
|
||||
# fota_info区填充(除hash以外,hash数据最后再填充)
|
||||
fota_info_len, fota_info_bin_buff = fill_fota_info_area(cf, image_num, fota_obj)
|
||||
|
||||
hash_node_offset = fota_key_len + fota_info_len
|
||||
all_hash_node_len = image_num * sizeof(fota_image_hash_node)
|
||||
tmp = all_hash_node_len % 16
|
||||
if tmp != 0:
|
||||
all_hash_node_len = all_hash_node_len + 16 - tmp
|
||||
# hash node 尾部多余长度
|
||||
tmp_hash_bin = bytearray(16 - tmp)
|
||||
|
||||
image_offset = hash_node_offset + all_hash_node_len
|
||||
all_image_len = 0
|
||||
temp_offset1 = [0]
|
||||
all_image_bin = bytearray(temp_offset1[0])
|
||||
temp_offset2 = [0]
|
||||
all_hash_bin_buff = bytearray(temp_offset2[0])
|
||||
|
||||
image_index = 0
|
||||
for image_confg_key in fota_obj.input_dict:
|
||||
#image_confg_key = 'IMAGE_' + str(i + 1)
|
||||
image_id = hex2dec(cf.get(image_confg_key, 'ImageId'))
|
||||
|
||||
# 填充升级镜像头部结构,返回镜像总长度(压缩后的实际长度,不包含对齐的长度)和头结构的总长度、头部的非安全hash
|
||||
image_length = fill_fota_image(cf, image_confg_key, all_image_bin, fota_obj, all_image_len, image_offset)
|
||||
head_hash = make_sha256_unsecure_signature(all_image_bin[all_image_len : all_image_len + sizeof(fota_image_head)])
|
||||
# 计算下一个镜像的起始位置和偏移位置
|
||||
addr_offset = all_image_len + image_offset
|
||||
all_image_len = all_image_len + image_length
|
||||
# print(image_confg_key, ':', image_length, ': addr_offset:', addr_offset)
|
||||
# 将计算出来的镜像头hash放到hash段的bin中,并初始化hash的结构
|
||||
fill_fota_image_hash_node(all_hash_bin_buff, image_id, image_index, head_hash, addr_offset, image_length)
|
||||
image_index += 1 # 镜像索引递增
|
||||
|
||||
if tmp != 0:
|
||||
all_hash_bin_buff[all_hash_node_len - len(tmp_hash_bin):all_hash_node_len] = tmp_hash_bin
|
||||
|
||||
# 计算hash table表hash值,填到fota_info_area
|
||||
hash_table_hash = make_sha256_unsecure_signature(all_hash_bin_buff)
|
||||
set_fota_info_area(fota_info_len, fota_info_bin_buff, hash_node_offset, all_hash_node_len, hash_table_hash)
|
||||
|
||||
upg_bin[0:fota_key_len] = fota_key_bin_buff
|
||||
upg_bin[fota_key_len:fota_key_len + fota_info_len] = fota_info_bin_buff
|
||||
upg_bin[hash_node_offset:hash_node_offset + all_hash_node_len] = all_hash_bin_buff
|
||||
upg_bin[image_offset:image_offset + all_image_len] = all_image_bin
|
||||
remove_file(fota_obj.upg_image)
|
||||
create_dirs(os.path.dirname(fota_obj.upg_image))
|
||||
with open(fota_obj.upg_image, 'wb+') as fp:
|
||||
fp.write(upg_bin)
|
||||
# print_upg(upg_bin, fota_obj.upg_image)
|
||||
return
|
||||
|
||||
def print_upg_byte_list(pname, byte_in):
|
||||
length = len(byte_in)
|
||||
print("[%s=0x"%pname, end="")
|
||||
for i in range(0, length):
|
||||
print("%02x"%byte_in[i], end="")
|
||||
print("]")
|
||||
|
||||
def print_upg_byte(pname, byte_in):
|
||||
length = len(byte_in)
|
||||
print("[%s ="%pname)
|
||||
for i in range(0, length):
|
||||
if (i + 1) % 16 != 0:
|
||||
print("0x%02x, " % byte_in[i], end="")
|
||||
elif (i + 1) == length:
|
||||
print("0x%02x]" % byte_in[i])
|
||||
else:
|
||||
print("0x%02x, " % byte_in[i])
|
||||
|
||||
def print_fota_key_area(fota_key_head):
|
||||
print("[image_id=0x%x]" % (fota_key_head.image_id))
|
||||
print("[struct_version=0x%x]" % (fota_key_head.struct_version))
|
||||
print("[struct_length=0x%x]" % (fota_key_head.struct_length))
|
||||
print("[signature_length=0x%x]" % (fota_key_head.signature_length))
|
||||
print("[key_owner_id=0x%x]" % (fota_key_head.key_owner_id))
|
||||
print("[key_id=0x%x]" % (fota_key_head.key_id))
|
||||
print("[key_alg=0x%x]]" % (fota_key_head.key_alg))
|
||||
print("[ecc_curve_type=0x%x]" % (fota_key_head.ecc_curve_type))
|
||||
print("[key_length=0x%x]]" % (fota_key_head.key_length))
|
||||
print("[fota_key_version_ext=0x%x]" % (fota_key_head.fota_key_version_ext))
|
||||
print("[mask_fota_key_version_ext=0x%x]" % (fota_key_head.mask_fota_key_version_ext))
|
||||
print("[msid_ext=0x%x]" % (fota_key_head.msid_ext))
|
||||
print("[mask_msid_ext=0x%x]" % (fota_key_head.mask_msid_ext))
|
||||
print("[maintenance_mode=0x%x]" % (fota_key_head.maintenance_mode))
|
||||
print_upg_byte("die_id", fota_key_head.die_id)
|
||||
print("[fota_info_addr=0x%x]]" % (fota_key_head.fota_info_addr))
|
||||
#print_upg_byte("reserved", fota_key_head.reserved)
|
||||
print_upg_byte("fota_external_public_key", fota_key_head.fota_external_public_key)
|
||||
print_upg_byte("sig_fota_key_area", fota_key_head.sig_fota_key_area)
|
||||
|
||||
def print_fota_info_area(fota_info_head):
|
||||
print("[image_id=0x%x]" % (fota_info_head.image_id))
|
||||
print("[struct_version=0x%x]" % (fota_info_head.struct_version))
|
||||
print("[struct_length=0x%x]" % (fota_info_head.struct_length))
|
||||
print("[signature_length=0x%x]" % (fota_info_head.signature_length))
|
||||
print("[fota_version_ext=0x%x]" % (fota_info_head.fota_version_ext))
|
||||
print("[mask_fota_version_ext=0x%x]" % (fota_info_head.mask_fota_version_ext))
|
||||
print("[msid_ext=0x%x]" % (fota_info_head.msid_ext))
|
||||
print("[mask_msid_ext=0x%x]" % (fota_info_head.mask_msid_ext))
|
||||
print("[image_hash_table_addr=0x%x]" % (fota_info_head.image_hash_table_addr))
|
||||
print("[image_hash_table_length=0x%x]" % (fota_info_head.image_hash_table_length))
|
||||
#print_upg_byte("image_hash_table_hash", fota_info_head.image_hash_table_hash)
|
||||
print_upg_byte_list("image_hash_table_hash", fota_info_head.image_hash_table_hash)
|
||||
print("[image_num=0x%x]" % (fota_info_head.image_num))
|
||||
print("[hardware_id=0x%x]" % (fota_info_head.hardware_id))
|
||||
#print_upg_byte("reserved", fota_info_head.reserved)
|
||||
print_upg_byte("sign_fota_info", fota_info_head.sign_fota_info)
|
||||
|
||||
def print_fota_image_hash_table(fota_image_hash_table):
|
||||
print("[image_id=0x%x]" % (fota_image_hash_table.image_id))
|
||||
print("[image_addr=0x%x]" % (fota_image_hash_table.image_addr))
|
||||
print("[image_length=0x%x]" % (fota_image_hash_table.image_length))
|
||||
#print_upg_byte("image_hash", fota_image_hash_table.image_hash)
|
||||
print_upg_byte_list("image_hash", fota_image_hash_table.image_hash)
|
||||
|
||||
def print_fota_image_head(image_head):
|
||||
print("[header_magic=0x%x]" % (image_head.header_magic))
|
||||
print("[image_id=0x%x]" % (image_head.image_id))
|
||||
print("[image_offset=0x%x]" % (image_head.image_offset))
|
||||
print("[image_len=0x%x]" % (image_head.image_len))
|
||||
print("[new_image_len=0x%x]" % (image_head.new_image_len))
|
||||
#print_upg_byte("new_image_hash", image_head.new_image_hash)
|
||||
print_upg_byte_list("image_hash", image_head.image_hash)
|
||||
print("[old_image_len=0x%x]" % (image_head.old_image_len))
|
||||
print_upg_byte_list("old_image_hash", image_head.old_image_hash)
|
||||
#print_upg_byte("old_image_hash", image_head.old_image_hash)
|
||||
print("[version_ext=0x%x]" % (image_head.version_ext))
|
||||
print("[version_mask=0x%x]" % (image_head.version_mask))
|
||||
print("[decompress_flag=0x%x]" % (image_head.decompress_flag))
|
||||
print("[root_key_type=0x%x]" % (image_head.root_key_type))
|
||||
print("[re_enc_flag=0x%x]" % (image_head.re_enc_flag))
|
||||
print_upg_byte("enc_pk_l1", image_head.enc_pk_l1)
|
||||
print_upg_byte("enc_pk_l2", image_head.enc_pk_l2)
|
||||
print_upg_byte("iv", image_head.iv)
|
||||
#print_upg_byte("padding", image_head.padding)
|
||||
|
||||
def print_upg(upg_bin, image_file):
|
||||
print("upg_bin_len %s"%len(upg_bin))
|
||||
print("-------------%s fota_key_area start-------------" % (image_file))
|
||||
fota_key_head = fota_key_area_data.from_buffer(upg_bin)
|
||||
key_area_len = fota_key_head.struct_length
|
||||
print_fota_key_area(fota_key_head)
|
||||
print("-------------%s fota_info_area start-------------" % (image_file))
|
||||
if fota_key_head.fota_info_addr == 0:
|
||||
fota_info_offset = key_area_len
|
||||
else:
|
||||
fota_info_offset = fota_key_head.fota_info_addr
|
||||
fota_info_head = fota_info_area_data.from_buffer(upg_bin[fota_info_offset:])
|
||||
print_fota_info_area(fota_info_head)
|
||||
|
||||
image_num = fota_info_head.image_num
|
||||
hash_node_size = sizeof(fota_image_hash_node)
|
||||
if fota_info_head.image_hash_table_addr == 0:
|
||||
hash_table_offset = fota_info_offset + key_area_len
|
||||
else:
|
||||
hash_table_offset = fota_info_head.image_hash_table_addr
|
||||
|
||||
for i in range(0, image_num):
|
||||
print("-------------fota hash table start NO.%02d-------------" % (i + 1))
|
||||
hash_table_info = fota_image_hash_node.from_buffer(upg_bin[hash_table_offset + i * hash_node_size:])
|
||||
print_fota_image_hash_table(hash_table_info)
|
||||
print("-------------fota image head start NO.%02d-------------" % (i + 1))
|
||||
image_head_offset = hash_table_info.image_addr
|
||||
image_head = fota_image_head.from_buffer(upg_bin[image_head_offset:])
|
||||
print_fota_image_head(image_head)
|
||||
|
||||
def get_parameters():
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument('-app_name', type=str, default='',
|
||||
help='生成镜像的应用名')
|
||||
|
||||
parser.add_argument('-upg_format_path', type=str, default='',
|
||||
help='升级包结构配置文件')
|
||||
|
||||
parser.add_argument('-base', type=str, default='',
|
||||
help='基础配置文件路径')
|
||||
|
||||
parser.add_argument('-temp_dir', type=str, default='',
|
||||
help='临时配置文件路径')
|
||||
|
||||
parser.add_argument('-old_images', type=str, default='',
|
||||
help='老版本镜像文件路径')
|
||||
|
||||
parser.add_argument('-new_images', type=str, default='',
|
||||
help='新版本镜像文件路径')
|
||||
|
||||
parser.add_argument('-output_dir', type=str, default='',
|
||||
help='输出文件路径')
|
||||
|
||||
parser.add_argument('-type', type=int, default=0,
|
||||
help='执行类型')
|
||||
|
||||
parser.add_argument('-sign_tool', type=int, default=0,
|
||||
help='签名工具选择 0-本地签名工具, 1-在线签名工具')
|
||||
config = parser.parse_args()
|
||||
return config
|
||||
|
||||
config_item = ['SignSuite', 'RootKeyFile', 'SubKeyFile', 'SrcFile', 'DstFile']
|
||||
class Properties:
|
||||
def getProperties(self, dir):
|
||||
# 处理升级配置文件,获取有效配置,将有效配置保存到字典中
|
||||
# 各个镜像的配置不一样,这部分也被过滤掉了,后面要怎么区分?
|
||||
#########################################################################
|
||||
properties = {}
|
||||
with open(dir, 'r', encoding='utf-8') as pro_file:
|
||||
for line in pro_file:
|
||||
if line.find('=') > 0 and '#' not in line:
|
||||
strs = line.replace('\n', '').split('=')
|
||||
properties[strs[0]] = strs[1]
|
||||
return properties
|
||||
|
||||
# 获取签名相关的配置
|
||||
def setProperties(self, dir, properties):
|
||||
with open(dir, 'w') as pro_file:
|
||||
for item in properties:
|
||||
if item in config_item:
|
||||
pro_file.write("{}={}\n".format(item, properties[item]))
|
||||
|
||||
def remove_file(path):
|
||||
if os.path.exists(path): # 如果文件存在
|
||||
# 删除文件,可使用以下两种方法。
|
||||
os.remove(path)
|
||||
def create_dirs(path):
|
||||
os.makedirs(path, exist_ok=True)
|
||||
|
||||
def print_fota_file(image_file):
|
||||
with open(image_file, 'rb') as fp:
|
||||
upg_bin = fp.read()
|
||||
print_upg_byte(image_file, upg_bin)
|
||||
|
||||
|
||||
class myconf(configparser.ConfigParser):
|
||||
def __init__(self, defaults=None):
|
||||
configparser.ConfigParser.__init__(self, defaults=defaults)
|
||||
|
||||
# 这里重写了optionxform方法,直接返回选项名
|
||||
def optionxform(self, optionstr):
|
||||
return optionstr
|
||||
|
||||
def create_upg_cfg(fota_obj, user_input):
|
||||
img_cfg = myconf()
|
||||
img_cfg.read(user_input.base, encoding='utf-8')
|
||||
cf_list = img_cfg.sections() # 获取所有section,返回值为list
|
||||
|
||||
input_cf_key_list = []
|
||||
input_cf_key_list.append('FOTA_KEY_AREA')
|
||||
input_cf_key_list.append('FOTA_INFO_AREA')
|
||||
|
||||
# 将输入的段加入到列表
|
||||
for image_confg_key in fota_obj.input_dict:
|
||||
input_cf_key_list.append(image_confg_key)
|
||||
|
||||
for item in cf_list:
|
||||
# 将基础配置文件中,和输入无关的段删除
|
||||
if item not in input_cf_key_list:
|
||||
img_cfg.remove_section(item)
|
||||
|
||||
remove_file(fota_obj.image_conf_file)
|
||||
create_dirs(os.path.dirname(fota_obj.image_conf_file))
|
||||
with open(fota_obj.image_conf_file, 'w') as configfile:
|
||||
img_cfg.write(configfile)
|
||||
|
||||
def create_sign_cfg(fota_obj):
|
||||
remove_file(fota_obj.sign_conf_file)
|
||||
create_dirs(os.path.dirname(fota_obj.sign_conf_file))
|
||||
# 从基础文件中读取SIGN_CFG段,并写入到签名配置文件
|
||||
with open(fota_obj.sign_conf_file, 'w') as pro_file:
|
||||
for item in fota_obj.base_cfg.items("SIGN_CFG"):
|
||||
if item[0] == 'UpgImagePath':
|
||||
pro_file.write('SrcFile="%s"\n'%fota_obj.upg_image)
|
||||
elif item[0] == 'UpgSignedImagePath':
|
||||
pro_file.write('DstFile="%s"\n'%fota_obj.upg_signed_image)
|
||||
elif item[0] == 'RootKeyFile':
|
||||
pro_file.write('RootKeyFile="%s"\n'% os.path.join(fota_obj.root_path, fota_obj.base_cfg.get('SIGN_CFG', 'RootKeyFile')))
|
||||
elif item[0] == 'SubKeyFile':
|
||||
pro_file.write('SubKeyFile="%s"\n'% os.path.join(fota_obj.root_path, fota_obj.base_cfg.get('SIGN_CFG', 'SubKeyFile')))
|
||||
else:
|
||||
pro_file.write('%s=%s\n'%item)
|
||||
for item in fota_obj.base_cfg.items("FOTA_KEY_AREA"):
|
||||
if item[0] == 'ImageId':
|
||||
pro_file.write('%s=%s\n'%item)
|
||||
|
||||
def check_fota_image_id(fota_file):
|
||||
# 各个镜像的image_id需保证不一致
|
||||
cf = myconf()
|
||||
cf.read(fota_file, encoding='utf-8')
|
||||
cf_list = cf.sections()
|
||||
image_id_dict = {}
|
||||
no_sections = ['FOTA_KEY_AREA', 'FOTA_INFO_AREA']
|
||||
if cf.get('FOTA_KEY_AREA', 'ImageId') != cf.get('FOTA_INFO_AREA', 'ImageId'):
|
||||
msg = "FOTA_KEY_AREA and FOTA_INFO_AREA have different ImageId.\n"
|
||||
sys.exit(msg)
|
||||
for section in cf_list:
|
||||
if section in no_sections:
|
||||
continue
|
||||
image_id = cf.get(section, 'ImageId')
|
||||
if image_id in image_id_dict:
|
||||
msg = "The ImageId of %s and %s are the same.\n" % (section, image_id_dict.get(image_id))
|
||||
sys.exit(msg)
|
||||
else:
|
||||
image_id_dict[image_id] = section
|
||||
|
||||
def check_image_key(input_dict):
|
||||
# 检查nv是否与主程序一起打包
|
||||
pkg_bin_list = input_dict.keys()
|
||||
if 'nv' in pkg_bin_list and 'application' not in pkg_bin_list:
|
||||
msg = "The NV cannot be packed separately.It has to be with application!\n"
|
||||
sys.exit(msg)
|
||||
|
||||
# 检查索引文件与资源文件是否在一起打包
|
||||
if 'res_data' in pkg_bin_list and 'res_index' not in pkg_bin_list:
|
||||
msg = "The res_index file and res_data should be together.\n"
|
||||
sys.exit(msg)
|
||||
|
||||
def sign_upg_file(fota_obj):
|
||||
if fota_obj.sign_tool == 1:
|
||||
# 在线签名,将不会在fota_obj.output_dir下生成最终升级包文件
|
||||
# 需usr自行对fota_obj.temp_dir下的未签名文件update_temp.fwpkg进行签名
|
||||
return
|
||||
cmd = ' '.join([fota_obj.upg_tool, '3', '"%s"' % fota_obj.sign_conf_file])
|
||||
subprocess.run(cmd, shell=True)
|
||||
|
||||
class fota_info:
|
||||
def __init__(self, user_input):
|
||||
self.root_path = g_root
|
||||
self.app_name = user_input.app_name
|
||||
self.temp_dir = user_input.temp_dir
|
||||
self.output_dir = user_input.output_dir
|
||||
self.image_conf_file = os.path.join(self.temp_dir, '%s.cfg' % user_input.app_name) # 升级镜像的配置文件
|
||||
self.sign_conf_file = os.path.join(self.temp_dir, '%s_sign.cfg' % user_input.app_name) # 升级镜像的签名配置文件
|
||||
self.encry_conf_file = os.path.join(self.temp_dir, '%s_encry.cfg' % user_input.app_name) # 升级镜像的加密配置文件
|
||||
if hasattr(user_input, 'sign_tool'):
|
||||
self.sign_tool = user_input.sign_tool
|
||||
else:
|
||||
self.sign_tool = 0
|
||||
|
||||
if hasattr(user_input, 'hardware_id'):
|
||||
self.hardware_id = user_input.hardware_id
|
||||
|
||||
self.base_cfg = myconf()
|
||||
self.base_cfg.read(user_input.base, encoding='utf-8')
|
||||
self.temp_base_cfg = myconf()
|
||||
self.temp_base_cfg.read(user_input.temp_base, encoding='utf-8')
|
||||
# 同步模板数据到配置文件
|
||||
self._sync_upg_cfg(user_input)
|
||||
self._set_upg_image_path()
|
||||
self._set_tool_path()
|
||||
|
||||
self.input_dict = self._split_input_info(user_input.new_images)
|
||||
self.original_dict = self._split_input_info(user_input.old_images)
|
||||
self.diff_image_info = self._get_image_path_for_diff_image(self.input_dict, self.original_dict) # 差分镜像信息
|
||||
|
||||
def _sync_upg_cfg(self, user_input):
|
||||
# 从模板配置文件中读取秘钥、工具段,并写入到ota配置文件
|
||||
self.base_cfg.set('SIGN_CFG', 'SignSuite', self.temp_base_cfg.get('SIGN_CFG', 'SignSuite'))
|
||||
self.base_cfg.set('SIGN_CFG', 'RootKeyFile', self.temp_base_cfg.get('SIGN_CFG', 'RootKeyFile'))
|
||||
self.base_cfg.set('SIGN_CFG', 'SubKeyFile', self.temp_base_cfg.get('SIGN_CFG', 'SubKeyFile'))
|
||||
self.base_cfg.set('FOTA_KEY_AREA', 'KeyAlg', self.temp_base_cfg.get('FOTA_KEY_AREA', 'KeyAlg'))
|
||||
self.base_cfg.set('application', 'ProtectionKeyL1', self.temp_base_cfg.get('application', 'ProtectionKeyL1'))
|
||||
self.base_cfg.set('application', 'ProtectionKeyL2', self.temp_base_cfg.get('application', 'ProtectionKeyL2'))
|
||||
self.base_cfg.set('application', 'PlainKey', self.temp_base_cfg.get('application', 'PlainKey'))
|
||||
self.base_cfg.set('application', 'Iv', self.temp_base_cfg.get('application', 'Iv'))
|
||||
self.base_cfg.set('application', 'ReRncFlag', self.temp_base_cfg.get('application', 'ReRncFlag'))
|
||||
self.base_cfg.set('TOOLS', 'UpgToolPath', self.temp_base_cfg.get('TOOLS', 'UpgToolPath'))
|
||||
self.base_cfg.set('TOOLS', 'LzmaToolPath', self.temp_base_cfg.get('TOOLS', 'LzmaToolPath'))
|
||||
with open(user_input.base, 'w') as pro_file:
|
||||
self.base_cfg.write(pro_file)
|
||||
|
||||
def _set_tool_path(self):
|
||||
if platform.system().lower() == "linux":
|
||||
self.upg_tool = self.base_cfg.get('TOOLS', 'UpgToolPath')
|
||||
self.lzma_tool = self.base_cfg.get('TOOLS', 'LzmaToolPath')
|
||||
elif platform.system().lower() == "windows":
|
||||
self.upg_tool = self.base_cfg.get('TOOLS', 'UpgToolWinPath')
|
||||
self.lzma_tool = self.base_cfg.get('TOOLS', 'LzmaToolWinPath')
|
||||
self.upg_tool = '"%s"' % os.path.join(self.root_path, self.upg_tool)
|
||||
self.lzma_tool = '"%s"' % os.path.join(self.root_path, self.lzma_tool)
|
||||
print("upg_tool:", self.upg_tool)
|
||||
print("lzma_tool:", self.lzma_tool)
|
||||
|
||||
def _set_upg_image_path(self):
|
||||
self.upg_image = self.base_cfg.get('SIGN_CFG', 'UpgImagePath')
|
||||
self.upg_signed_image = self.base_cfg.get('SIGN_CFG', 'UpgSignedImagePath')
|
||||
if self.upg_image == '':
|
||||
self.upg_image = os.path.join(self.temp_dir, '%s_temp.fwpkg' % self.app_name)
|
||||
if self.upg_signed_image == '':
|
||||
self.upg_signed_image = os.path.join(self.output_dir, '%s.fwpkg' % self.app_name)
|
||||
|
||||
def _split_input_info(self, input):
|
||||
input = input.replace('\n','').replace('\r','').replace('\t','')
|
||||
if input == '':
|
||||
return None
|
||||
|
||||
bin_list = input.split('|')
|
||||
image_num = len(bin_list)
|
||||
bin_dict = {}
|
||||
res_data = ""
|
||||
for i in range(0, image_num):
|
||||
bin_file, image_confg_key = bin_list[i].split('=')
|
||||
if image_confg_key == "res_data":
|
||||
res_data = bin_file
|
||||
else:
|
||||
bin_dict[image_confg_key] = bin_file
|
||||
|
||||
if res_data != "":
|
||||
bin_dict["res_data"] = res_data
|
||||
|
||||
return bin_dict
|
||||
|
||||
def _get_image_path_for_diff_image(self, new_version_dict, org_version_dict):
|
||||
# 解析各个镜像的老版本镜像路径、新版本路径,并一一对应
|
||||
# 制作差分升级文件的镜像需要提供老版本文件路径,提供老版本的同时也必须提供对应的新版本路径
|
||||
if org_version_dict == None:
|
||||
return None
|
||||
|
||||
image_ref = {}
|
||||
for image_confg_key in org_version_dict:
|
||||
if image_confg_key in image_ref:
|
||||
sys.exit("[ERROR] old_images bin param repeated!!!")
|
||||
image_ref[image_confg_key] = [
|
||||
org_version_dict[image_confg_key], # 存放老镜像路径
|
||||
"", # 存放新镜像路径
|
||||
"" # 存放镜像路径的前缀,取新路径前缀
|
||||
]
|
||||
|
||||
for image_confg_key in new_version_dict:
|
||||
if image_confg_key in image_ref:
|
||||
image_ref[image_confg_key][1] = new_version_dict[image_confg_key] # 后存放新版本镜像到1
|
||||
image_ref[image_confg_key][2] = os.path.splitext(os.path.basename(image_ref[image_confg_key][0]))[0]
|
||||
|
||||
for key in image_ref:
|
||||
if image_ref[key][1] == "":
|
||||
sys.exit("[ERROR] not find a matched image bin!!!")
|
||||
return image_ref
|
||||
|
||||
def create_fota_file(user_input):
|
||||
fota_format_init(user_input.upg_format_path)
|
||||
fota_obj = fota_info(user_input)
|
||||
# 检查打包镜像限制
|
||||
check_image_key(fota_obj.input_dict)
|
||||
# 生成镜像配置文件
|
||||
create_upg_cfg(fota_obj, user_input)
|
||||
# 镜像ID校验
|
||||
check_fota_image_id(fota_obj.image_conf_file)
|
||||
# 升级文件制作
|
||||
make_upg(fota_obj)
|
||||
# 生成签名配置文件
|
||||
create_sign_cfg(fota_obj)
|
||||
# 升级文件签名
|
||||
sign_upg_file(fota_obj)
|
||||
# 清空临时文件
|
||||
shutil.rmtree(fota_obj.temp_dir)
|
||||
|
||||
def begin(user_input):
|
||||
if user_input.type == 0:
|
||||
create_fota_file(user_input)
|
||||
else:
|
||||
print_fota_file(user_input.new_images)
|
||||
|
||||
if __name__ == "__main__":
|
||||
user_input = get_parameters()
|
||||
begin(user_input)
|
99
build/config/target_config/ws63/sign_encry/build_ota_pkt.py
Executable file
99
build/config/target_config/ws63/sign_encry/build_ota_pkt.py
Executable file
@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env python3
|
||||
# encoding=utf-8
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
g_root = os.path.dirname(os.path.realpath(__file__))
|
||||
sys.path.append(os.path.join(g_root))
|
||||
from build_ota_img import begin
|
||||
|
||||
|
||||
class upg_base_info:
|
||||
def __init__(self, conf):
|
||||
path_str = conf.path.split(",")
|
||||
input_path = path_str[0]
|
||||
output_path = path_str[1]
|
||||
|
||||
self.root_path = g_root
|
||||
# 升级包结构配置文件
|
||||
self.fota_format_path = os.path.join(self.root_path, "config", "ota")
|
||||
# 升级配置文件模板
|
||||
self.temp_fota_cfg = os.path.join(self.root_path, "config", "ota", "fota_template.cfg")
|
||||
# 升级配置文件
|
||||
self.fota_cfg = os.path.join(self.root_path, input_path, "fota.cfg")
|
||||
# 镜像输入路径
|
||||
self.output = os.path.join(self.root_path, input_path)
|
||||
# 升级镜像包输出路径
|
||||
self.upg_output = os.path.join(self.root_path, output_path)
|
||||
# 升级制作临时文件输出路径
|
||||
self.temp_dir = os.path.join(self.upg_output, "tmp_ota_cfg")
|
||||
print("\ninput_dir:", self.output)
|
||||
print("output_dir:", self.upg_output)
|
||||
# 产品镜像路径
|
||||
self.flashboot = os.path.join(self.output, "flashboot_sign.bin")
|
||||
self.app_bin = os.path.join(self.output, "ws63-liteos-app_sign.bin")
|
||||
self.test_bin = os.path.join(self.output, "ws63-liteos-testsuite_sign.bin")
|
||||
self.nv_bin = os.path.join(self.output, "ws63_all_nv.bin")
|
||||
|
||||
self.flashboot_old_bin = os.path.join(self.output, "flashboot_sign.bin")
|
||||
self.app_old_bin = os.path.join(self.output, "ws63-liteos-app_sign.bin")
|
||||
self.test_old_bin = os.path.join(self.output, "ws63-liteos-testsuite_sign.bin")
|
||||
self.nv_old_bin = os.path.join(self.output, "ws63_all_nv.bin")
|
||||
|
||||
def get_new_image(input,info):
|
||||
image_list = []
|
||||
if 'app' in input:
|
||||
image_list.append("=".join([info.app_bin, "application"]))
|
||||
if 'test' in input:
|
||||
image_list.append("=".join([info.test_bin, "application"]))
|
||||
if 'boot' in input:
|
||||
image_list.append("=".join([info.flashboot, "flashboot"]))
|
||||
if 'nv' in input:
|
||||
image_list.append("=".join([info.nv_bin, "nv"]))
|
||||
|
||||
new_image = "|".join(image_list)
|
||||
return new_image
|
||||
|
||||
|
||||
def get_old_image(input,info):
|
||||
image_list = []
|
||||
if 'app' in input:
|
||||
image_list.append("=".join([info.app_old_bin, "application"]))
|
||||
if 'test' in input:
|
||||
image_list.append("=".join([info.test_old_bin, "application"]))
|
||||
if 'boot' in input:
|
||||
image_list.append("=".join([info.flashboot_old_bin, "flashboot"]))
|
||||
if 'nv' in input:
|
||||
image_list.append("=".join([info.nv_old_bin, "nv"]))
|
||||
|
||||
old_image = "|".join(image_list)
|
||||
return old_image
|
||||
|
||||
def get_parameters():
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument('--pkt', type=str, default = 'app',
|
||||
help='需要生成的镜像,包括: app,boot,nv')
|
||||
|
||||
parser.add_argument('--path', type=str, default = '../input',
|
||||
help='待打包镜像路径 and 输出路径: ../input,../output')
|
||||
|
||||
config = parser.parse_args()
|
||||
return config
|
||||
|
||||
if __name__ == '__main__':
|
||||
conf = get_parameters()
|
||||
info = upg_base_info(conf)
|
||||
input = conf.pkt.split(",")
|
||||
conf.app_name = "update_encry"
|
||||
conf.upg_format_path = info.fota_format_path
|
||||
conf.base = info.fota_cfg
|
||||
conf.temp_base = info.temp_fota_cfg
|
||||
conf.temp_dir = info.temp_dir
|
||||
conf.new_images = get_new_image(input,info)
|
||||
conf.old_images = get_old_image(input,info)
|
||||
conf.output_dir = info.upg_output
|
||||
conf.type = 0
|
||||
begin(conf)
|
71
build/config/target_config/ws63/sign_encry/config/ota/fota_format_st.py
Executable file
71
build/config/target_config/ws63/sign_encry/config/ota/fota_format_st.py
Executable file
@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python3
|
||||
# coding=utf-8
|
||||
|
||||
'''
|
||||
* Copyright HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Description: part of hupg build scripts
|
||||
'''
|
||||
|
||||
import struct
|
||||
from ctypes import *
|
||||
|
||||
###############################Defining Basic Types###############################################
|
||||
td_char = c_char
|
||||
td_s8 = c_byte
|
||||
td_u8 = c_ubyte
|
||||
td_s16 = c_short
|
||||
td_u16 = c_ushort
|
||||
td_s32 = c_int
|
||||
td_u32 = c_uint
|
||||
|
||||
fota_key_area_data_fields = [
|
||||
("image_id", td_u32),
|
||||
("struct_version", td_u32),
|
||||
("struct_length", td_u32),
|
||||
("signature_length", td_u32),
|
||||
("key_owner_id", td_u32),
|
||||
("key_id", td_u32),
|
||||
("key_alg", td_u32),
|
||||
("ecc_curve_type", td_u32),
|
||||
("key_length", td_u32),
|
||||
("fota_key_version_ext", td_u32),
|
||||
("mask_fota_key_version_ext", td_u32),
|
||||
("msid_ext", td_u32),
|
||||
("mask_msid_ext", td_u32),
|
||||
("maintenance_mode", td_u32),
|
||||
("die_id", td_u8 * 16),
|
||||
("fota_info_addr", td_u32),
|
||||
("reserved", td_u8 * 52),
|
||||
("fota_external_public_key", td_u8 * 64),
|
||||
("sig_fota_key_area", td_u8 * 64),
|
||||
]
|
||||
|
||||
fota_info_area_data_fields = [
|
||||
("image_id", td_u32),
|
||||
("struct_version", td_u32),
|
||||
("struct_length", td_u32),
|
||||
("signature_length", td_u32),
|
||||
("fota_version_ext", td_u32),
|
||||
("mask_fota_version_ext", td_u32),
|
||||
("msid_ext", td_u32),
|
||||
("mask_msid_ext", td_u32),
|
||||
("image_hash_table_addr", td_u32),
|
||||
("image_hash_table_length", td_u32),
|
||||
("image_hash_table_hash", td_u8 * 32),
|
||||
("image_num", td_u32),
|
||||
("hardware_id", td_u32),
|
||||
("reserved", td_u8 * 112),
|
||||
("sign_fota_info", td_u8 * 64),
|
||||
]
|
137
build/config/target_config/ws63/sign_encry/config/ota/fota_template.cfg
Executable file
137
build/config/target_config/ws63/sign_encry/config/ota/fota_template.cfg
Executable file
@ -0,0 +1,137 @@
|
||||
# SignSuite : 签名秘钥类型
|
||||
# 0: ECDSA_SHA256
|
||||
# 1: ECDSA_SHA256_LEA_CTR
|
||||
# 2: ECDSA_SHA256_LEA_CBC_MAC
|
||||
# 3: ECDSA_SHA256_AES_CBC
|
||||
|
||||
# 10: SM2_SM3
|
||||
# 11: SM2_SM3_LEA_CTR
|
||||
# 12: SM2_SM3_LEA_CBC_MAC
|
||||
# 13: SM2_SM3_SM4_CBC
|
||||
|
||||
# 30: RSA 4096
|
||||
# 34: RSA 4096 - SHA256
|
||||
[SIGN_CFG]
|
||||
# 此SignSuite默认为非安全升级的34
|
||||
# 若想进行安全升级需改为30,并将下方[FOTA_KEY_AREA]中KeyAlg的值修改为0x2A13C845
|
||||
SignSuite=1
|
||||
UpgImagePath =
|
||||
UpgSignedImagePath =
|
||||
RootKeyFile=config/sign/ec_bp256_oem_root_private_key.pem
|
||||
SubKeyFile=config/sign/ec_bp256_app_private_key.pem
|
||||
|
||||
[TOOLS]
|
||||
UpgToolPath=sign_tool_pltuni
|
||||
LzmaToolPath=lzma_tool
|
||||
UpgToolWinPath=sign_tool_pltuni.exe
|
||||
LzmaToolWinPath=lzma_tool.exe
|
||||
|
||||
# Default Single sign mode. If there are 'RootKeyFileExt' & 'SubKeyFileExt' then means Double Sign mode.
|
||||
# RootKeyFileExt=
|
||||
# SubKeyFileExt=
|
||||
[FOTA_KEY_AREA]
|
||||
ImageId=0xCB8D154E
|
||||
StructVersion=0x00010000
|
||||
KeyOwnerId=0
|
||||
KeyId=0
|
||||
# KeyAlg :Algorithm of the external public key:
|
||||
# 0x2A13C812: ECC256_SHA256
|
||||
# 0x2A13C823: SM2_SM3
|
||||
# 0x2A13C845: RSA4096_SHA256
|
||||
# 0x2A13C856: SHA256(ECC256 FORMAT)
|
||||
# 0x2A13C867: SHA256(RSA4096)
|
||||
# 0x2A13C878: SM3_ONLY
|
||||
# Others: Invalid
|
||||
KeyAlg=0x2A13C812
|
||||
KeyVersion=0x00000000
|
||||
KeyVersionMask=0x00000000
|
||||
Msid=0x00000000
|
||||
MsidMask=0x00000000
|
||||
|
||||
[FOTA_INFO_AREA]
|
||||
ImageId=0xCB8D154E
|
||||
StructVersion=0x00010000
|
||||
Version=0x00000000
|
||||
VersionMask=0x00000000
|
||||
Msid=0x00000000
|
||||
MsidMask=0x00000000
|
||||
HardwareID=0
|
||||
|
||||
[application]
|
||||
HeaderMagic=0x464F5451
|
||||
ImageId=0x4B0F2D2D
|
||||
# DecompressFlag :升级镜像模式标记
|
||||
# 0x3C7896E1 - compressed image
|
||||
# 0x44494646 - diff image
|
||||
# other :原始镜像不处理
|
||||
# DecompressFlag=0x3C7896E1
|
||||
# DecompressFlag=0x44494646
|
||||
DecompressFlag=0x3C7896E1
|
||||
# ReRncFlag:升级镜像加密标记
|
||||
# 0x3C7896E1:加密
|
||||
# other:不加密
|
||||
ReRncFlag=0x3C7896E1
|
||||
# RootKeyType : 用于加密图像的根密钥,在ReEncFlag启用时有效
|
||||
# 0 - ODRK0, for TEE runtime FW image.
|
||||
# 1 - ODRK1, for Protocol and REE Application image.
|
||||
RootKeyType=0x0
|
||||
# 用于解密更新映像秘钥的派生参数盐值16byte,在ReEncFlag启用时有效
|
||||
ProtectionKeyL1=05E8741C53C8D50E754F66537B20B94F
|
||||
# 用于解密更新映像秘钥的派生参数盐值前12byte,在ReEncFlag启用时有效
|
||||
ProtectionKeyL2=4A22C22633B6CFA1722A83E5EE42A64E
|
||||
# 用于加密更新映像的加密保护密钥,在ReEncFlag启用时有效
|
||||
PlainKey=3C0DDAAC468299DB59CBD68193F9FAF6
|
||||
#70D37764279C2B086604078E8C577505DEF83C1FD6E4D47BB464CF172F91156C ABRK ota加密
|
||||
Iv=685CDDA25DE6F5BC7A38C4481629B626
|
||||
version_ext=0x00000000
|
||||
version_mask=0x00000000
|
||||
|
||||
[flashboot]
|
||||
HeaderMagic=0x464F5451
|
||||
ImageId=0x4B1E3C2D
|
||||
# DecompressFlag :升级镜像模式标记
|
||||
# 0x3C7896E1 - compressed image
|
||||
# 0x44494646 - diff image
|
||||
# other :原始镜像不处理
|
||||
DecompressFlag=0x3C7896E1
|
||||
# ReRncFlag:升级镜像加密标记
|
||||
# 0x3C7896E1:加密
|
||||
# other:不加密
|
||||
ReRncFlag=0x0
|
||||
# RootKeyType : 用于加密图像的根密钥,在ReEncFlag启用时有效
|
||||
# 0 - ODRK0, for TEE runtime FW image.
|
||||
# 1 - ODRK1, for Protocol and REE Application image.
|
||||
RootKeyType=0x0
|
||||
# 用于解密更新映像秘钥的派生参数盐值16,在ReEncFlag启用时有效
|
||||
ProtectionKeyL1=05E8741C53C8D50E754F66537B20B94F
|
||||
# 用于解密更新映像秘钥的派生参数盐值12,在ReEncFlag启用时有效
|
||||
ProtectionKeyL2=4A22C22633B6CFA1722A83E5EE42A64E
|
||||
# 用于加密更新映像的加密保护密钥,在ReEncFlag启用时有效
|
||||
PlainKey=3C0DDAAC468299DB59CBD68193F9FAF6
|
||||
Iv=685CDDA25DE6F5BC7A38C4481629B626
|
||||
version_ext=0x00000000
|
||||
version_mask=0x00000000
|
||||
|
||||
[nv]
|
||||
HeaderMagic=0x464F5451
|
||||
ImageId=0xCB9E063C
|
||||
# DecompressFlag :升级镜像模式标记
|
||||
# 0 :原始镜像不处理 (nv只能使用该值)
|
||||
DecompressFlag=0x0
|
||||
# ReRncFlag:升级镜像加密标记
|
||||
# 0x3C7896E1:加密
|
||||
# other:不加密
|
||||
ReRncFlag=0x0
|
||||
# RootKeyType : 用于加密图像的根密钥,在ReEncFlag启用时有效
|
||||
# 0 - ODRK0, for TEE runtime FW image.
|
||||
# 1 - ODRK1, for Protocol and REE Application image.
|
||||
RootKeyType=0x0
|
||||
# 用于解密更新映像秘钥的派生参数盐值16,在ReEncFlag启用时有效
|
||||
ProtectionKeyL1=05E8741C53C8D50E754F66537B20B94F
|
||||
# 用于解密更新映像秘钥的派生参数盐值12,在ReEncFlag启用时有效
|
||||
ProtectionKeyL2=4A22C22633B6CFA1722A83E5EE42A64E
|
||||
# 用于加密更新映像的加密保护密钥,在ReEncFlag启用时有效
|
||||
PlainKey=3C0DDAAC468299DB59CBD68193F9FAF6
|
||||
Iv=685CDDA25DE6F5BC7A38C4481629B626
|
||||
version_ext=0x00000000
|
||||
version_mask=0x00000000
|
6
build/config/target_config/ws63/sign_encry/config/sign/encry_config.cfg
Executable file
6
build/config/target_config/ws63/sign_encry/config/sign/encry_config.cfg
Executable file
@ -0,0 +1,6 @@
|
||||
# Omrk1为派生flash秘钥参数1,需要写到efuse的otp_oem_mrk(KM): 0x44008858[0]-0x44008874[15]
|
||||
# OwnerId为派生flash秘钥参数2,固定为0,对应efuse的obfu_mrk1_owner_id(KM): 0x44008854[0]-0x44008854[15] (efuse默认为0不需要写)
|
||||
# OkpSalt值在签名加密前会被自动拷贝到镜像头的ProtectionKeyL1/2参数前28byte中
|
||||
Omrk1=3D05A72AEDFF69D82E9C10D3E01D9492
|
||||
OwnerId=0
|
||||
OkpSalt=05E8741C53C8D50E754F66537B20B94F4A22C22633B6CFA1722A83E5
|
@ -0,0 +1,29 @@
|
||||
SignSuite=0
|
||||
|
||||
SrcFile=flashboot.bin
|
||||
DstFile=flashboot_backup_sign.bin
|
||||
|
||||
RootKeyFile=ec_bp256_ssb_private_key.pem
|
||||
SubKeyFile=ec_bp256_flashboot_private_key.pem
|
||||
|
||||
ImageId=0x4B69871E
|
||||
CodeInfoImageId=0x4B69872D
|
||||
KeyOwnerId=1
|
||||
KeyId=1
|
||||
KeyAlg=0x2A13C812
|
||||
KeyVersion=0x00000000
|
||||
KeyVersionMask=0x00000000
|
||||
Msid=0x00000000
|
||||
MsidMask=0x00000000
|
||||
CompressFlag=0
|
||||
|
||||
Version=0x00000000
|
||||
VersionMask=0x00000000
|
||||
|
||||
ProtectionKeyL1=00112233445566778899AABBCCDDEEFF
|
||||
ProtectionKeyL2=00112233445566778899AABBCCDDEEFF
|
||||
PlainKey=04040404040404040404040404040404
|
||||
PlainKeyAuth=04040404040404040404040404040404
|
||||
# Iv=101112131415161718191A1B1C1D1E1F
|
||||
TextSegmentSize=0x00010000
|
||||
RamSize=0x00010000
|
29
build/config/target_config/ws63/sign_encry/config/sign/flash_bin_ecc.cfg
Executable file
29
build/config/target_config/ws63/sign_encry/config/sign/flash_bin_ecc.cfg
Executable file
@ -0,0 +1,29 @@
|
||||
SignSuite=0
|
||||
|
||||
SrcFile=flashboot.bin
|
||||
DstFile=flashboot_sign.bin
|
||||
|
||||
RootKeyFile=ec_bp256_ssb_private_key.pem
|
||||
SubKeyFile=ec_bp256_flashboot_private_key.pem
|
||||
|
||||
ImageId=0x4B1E3C1E
|
||||
CodeInfoImageId=0x4B1E3C2D
|
||||
KeyOwnerId=1
|
||||
KeyId=1
|
||||
KeyAlg=0x2A13C812
|
||||
KeyVersion=0x00000000
|
||||
KeyVersionMask=0x00000000
|
||||
Msid=0x00000000
|
||||
MsidMask=0x00000000
|
||||
CompressFlag=0
|
||||
|
||||
Version=0x00000000
|
||||
VersionMask=0x00000000
|
||||
|
||||
ProtectionKeyL1=00112233445566778899AABBCCDDEEFF
|
||||
ProtectionKeyL2=00112233445566778899AABBCCDDEEFF
|
||||
PlainKey=04040404040404040404040404040404
|
||||
PlainKeyAuth=04040404040404040404040404040404
|
||||
# Iv=101112131415161718191A1B1C1D1E1F
|
||||
TextSegmentSize=0x00010000
|
||||
RamSize=0x00010000
|
@ -0,0 +1,34 @@
|
||||
# 0: none encrypt
|
||||
# 1: flash encrypt
|
||||
SignSuite=1
|
||||
|
||||
SrcFile=ws63-liteos-app.bin
|
||||
DstFile=ws63-liteos-app-sign.bin
|
||||
|
||||
RootKeyFile=ec_bp256_flashboot_private_key.pem
|
||||
SubKeyFile=ec_bp256_app_private_key.pem
|
||||
|
||||
ImageId=0x4B0F2D1E
|
||||
CodeInfoImageId=0x4B0F2D2D
|
||||
KeyOwnerId=1
|
||||
KeyId=1
|
||||
KeyAlg=0x2A13C812
|
||||
KeyVersion=0x00000000
|
||||
KeyVersionMask=0x00000000
|
||||
Msid=0x00000000
|
||||
MsidMask=0x00000000
|
||||
CompressFlag=0
|
||||
|
||||
Version=0x00000000
|
||||
VersionMask=0x00000000
|
||||
|
||||
ProtectionKeyL1=05E8741C53C8D50E754F66537B20B94F
|
||||
ProtectionKeyL2=4A22C22633B6CFA1722A83E5EE42A64E
|
||||
|
||||
PlainKey=2D7154B26B81301730246E8F30E6DC98
|
||||
#8ABDA082DB74753577FF2D1E7D79DAC7 6D8116DF07F92FCBCCD1A3093A63462E
|
||||
PlainKeyAuth=04040404040404040404040404040404
|
||||
Iv=685CDDA25DE6F5BC7A38C4481629B626
|
||||
|
||||
TextSegmentSize=0x00010000
|
||||
RamSize=0x00010000
|
@ -0,0 +1,34 @@
|
||||
# 0: none encrypt
|
||||
# 1: flash encrypt
|
||||
SignSuite=0
|
||||
|
||||
SrcFile=ws63-liteos-app.bin
|
||||
DstFile=ws63-liteos-app-sign.bin
|
||||
|
||||
RootKeyFile=ec_bp256_flashboot_private_key.pem
|
||||
SubKeyFile=ec_bp256_app_private_key.pem
|
||||
|
||||
ImageId=0x4B0F2D1E
|
||||
CodeInfoImageId=0x4B0F2D2D
|
||||
KeyOwnerId=1
|
||||
KeyId=1
|
||||
KeyAlg=0x2A13C812
|
||||
KeyVersion=0x00000000
|
||||
KeyVersionMask=0x00000000
|
||||
Msid=0x00000000
|
||||
MsidMask=0x00000000
|
||||
CompressFlag=0
|
||||
|
||||
Version=0x00000000
|
||||
VersionMask=0x00000000
|
||||
|
||||
ProtectionKeyL1=05E8741C53C8D50E754F66537B20B94F
|
||||
ProtectionKeyL2=4A22C22633B6CFA1722A83E5EE42A64E
|
||||
|
||||
PlainKey=2D7154B26B81301730246E8F30E6DC98
|
||||
#8ABDA082DB74753577FF2D1E7D79DAC7 6D8116DF07F92FCBCCD1A3093A63462E
|
||||
PlainKeyAuth=04040404040404040404040404040404
|
||||
Iv=685CDDA25DE6F5BC7A38C4481629B626
|
||||
|
||||
TextSegmentSize=0x00010000
|
||||
RamSize=0x00010000
|
@ -0,0 +1,34 @@
|
||||
# 0: none encrypt
|
||||
# 1: flash encrypt
|
||||
SignSuite=0
|
||||
|
||||
SrcFile=ws63-liteos-mfg.bin
|
||||
DstFile=ws63-liteos-mfg-sign.bin
|
||||
|
||||
RootKeyFile=ec_bp256_flashboot_private_key.pem
|
||||
SubKeyFile=ec_bp256_app_private_key.pem
|
||||
|
||||
ImageId=0x4B7CF333
|
||||
CodeInfoImageId=0x4B0F2D2D
|
||||
KeyOwnerId=1
|
||||
KeyId=1
|
||||
KeyAlg=0x2A13C812
|
||||
KeyVersion=0x00000000
|
||||
KeyVersionMask=0x00000000
|
||||
Msid=0x00000000
|
||||
MsidMask=0x00000000
|
||||
CompressFlag=0
|
||||
|
||||
Version=0x00000000
|
||||
VersionMask=0x00000000
|
||||
|
||||
ProtectionKeyL1=8B5019052A0C4C79AB075F6F7819F838
|
||||
ProtectionKeyL2=143015DB334187A9126989F424201427
|
||||
|
||||
PlainKey=BD65DB90C9BC19E6BEE91AAEE0A27DCC
|
||||
#8ABDA082DB74753577FF2D1E7D79DAC7 6D8116DF07F92FCBCCD1A3093A63462E
|
||||
PlainKeyAuth=04040404040404040404040404040404
|
||||
Iv=63FFF3300CD91E3FCC0853D0BB1387F4
|
||||
|
||||
TextSegmentSize=0x00010000
|
||||
RamSize=0x00010000
|
@ -0,0 +1,31 @@
|
||||
SignSuite=0
|
||||
|
||||
SrcFile=loaderboot.bin
|
||||
DstFile=loaderboot_sign.bin
|
||||
|
||||
RootKeyFile=ec_bp256_oem_root_private_key.pem
|
||||
SubKeyFile=ec_bp256_loaderboot_private_key.pem
|
||||
|
||||
ImageId=0x4BD2F01E
|
||||
CodeInfoImageId=0x4BD2F02D
|
||||
KeyOwnerId=1
|
||||
KeyId=1
|
||||
KeyAlg=0x2A13C812
|
||||
KeyVersion=0x00000000
|
||||
KeyVersionMask=0x00000000
|
||||
Msid=0x00000000
|
||||
MsidMask=0x00000000
|
||||
CompressFlag=0
|
||||
|
||||
Version=0x00000000
|
||||
VersionMask=0x00000000
|
||||
|
||||
ProtectionKeyL1=00112233445566778899AABBCCDDEEFF
|
||||
ProtectionKeyL2=00112233445566778899AABBCCDDEEFF
|
||||
PlainKey=04040404040404040404040404040404
|
||||
|
||||
PlainKeyAuth=04040404040404040404040404040404
|
||||
Iv=101112131415161718191A1B1C1D1E1F
|
||||
|
||||
TextSegmentSize=0x00010000
|
||||
RamSize=0x00010000
|
6
build/config/target_config/ws63/sign_encry/config/sign/ota_sign.cfg
Executable file
6
build/config/target_config/ws63/sign_encry/config/sign/ota_sign.cfg
Executable file
@ -0,0 +1,6 @@
|
||||
SignSuite=30
|
||||
SrcFile="/disk1/c00585475/chengang/63/codes1/output/ws63/upgrade/temp_dir/update_temp.fwpkg"
|
||||
DstFile="/disk1/c00585475/chengang/63/codes1/output/ws63/upgrade/update.fwpkg"
|
||||
RootKeyFile="/disk1/c00585475/chengang/63/codes1/build/config/target_config/ws63/sign_config/ec_bp256_oem_root_public_key.pem"
|
||||
SubKeyFile="/disk1/c00585475/chengang/63/codes1/build/config/target_config/ws63/sign_config/ec_bp256_oem_root_public_key.pem"
|
||||
ImageId=0xCB8D154E
|
30
build/config/target_config/ws63/sign_encry/config/sign/param_bin_ecc.cfg
Executable file
30
build/config/target_config/ws63/sign_encry/config/sign/param_bin_ecc.cfg
Executable file
@ -0,0 +1,30 @@
|
||||
SignSuite=0
|
||||
|
||||
SrcFile=params.bin
|
||||
DstFile=params_sign.bin
|
||||
|
||||
RootKeyFile=ec_bp256_oem_root_private_key.pem
|
||||
SubKeyFile=ec_bp256_param_private_key.pem
|
||||
|
||||
ImageId=0x4B87A51E
|
||||
CodeInfoImageId=0x4B87A52D
|
||||
KeyOwnerId=1
|
||||
KeyId=1
|
||||
KeyAlg=0x2A13C812
|
||||
KeyVersion=0x00000000
|
||||
KeyVersionMask=0x00000000
|
||||
Msid=0x00000000
|
||||
MsidMask=0x00000000
|
||||
CompressFlag=0
|
||||
|
||||
Version=0x00000000
|
||||
VersionMask=0x00000000
|
||||
|
||||
ProtectionKeyL1=00112233445566778899AABBCCDDEEFF
|
||||
ProtectionKeyL2=00112233445566778899AABBCCDDEEFF
|
||||
PlainKey=04040404040404040404040404040404
|
||||
PlainKeyAuth=04040404040404040404040404040404
|
||||
Iv=101112131415161718191A1B1C1D1E1F
|
||||
|
||||
TextSegmentSize=0x00010000
|
||||
RamSize=0x00010000
|
8
build/config/target_config/ws63/sign_encry/config/sign/root_pubk.cfg
Executable file
8
build/config/target_config/ws63/sign_encry/config/sign/root_pubk.cfg
Executable file
@ -0,0 +1,8 @@
|
||||
SignSuite=0
|
||||
|
||||
SrcFile=ec_bp256_oem_root_private_key.pem
|
||||
DstFile=root_pubk.bin
|
||||
|
||||
ImageId=0x4BA5C31E
|
||||
KeyOwnerId=1
|
||||
KeyId=1
|
29
build/config/target_config/ws63/sign_encry/config/sign/ssb_bin_ecc.cfg
Executable file
29
build/config/target_config/ws63/sign_encry/config/sign/ssb_bin_ecc.cfg
Executable file
@ -0,0 +1,29 @@
|
||||
SignSuite=0
|
||||
|
||||
SrcFile=ssb.bin
|
||||
DstFile=ssb_sign.bin
|
||||
|
||||
RootKeyFile=ec_bp256_oem_root_private_key.pem
|
||||
SubKeyFile=ec_bp256_ssb_private_key.pem
|
||||
|
||||
ImageId=0x4B1E3C1E
|
||||
CodeInfoImageId=0x4B1E3C2D
|
||||
KeyOwnerId=1
|
||||
KeyId=1
|
||||
KeyAlg=0x2A13C812
|
||||
KeyVersion=0x00000000
|
||||
KeyVersionMask=0x00000000
|
||||
Msid=0x00000000
|
||||
MsidMask=0x00000000
|
||||
CompressFlag=0
|
||||
|
||||
Version=0x00000000
|
||||
VersionMask=0x00000000
|
||||
|
||||
ProtectionKeyL1=00112233445566778899AABBCCDDEEFF
|
||||
ProtectionKeyL2=00112233445566778899AABBCCDDEEFF
|
||||
PlainKey=04040404040404040404040404040404
|
||||
PlainKeyAuth=04040404040404040404040404040404
|
||||
Iv=101112131415161718191A1B1C1D1E1F
|
||||
TextSegmentSize=0x00010000
|
||||
RamSize=0x00010000
|
162
build/config/target_config/ws63/sign_encry/efuse_cfg_gen.py
Executable file
162
build/config/target_config/ws63/sign_encry/efuse_cfg_gen.py
Executable file
@ -0,0 +1,162 @@
|
||||
#!/usr/bin/env python3
|
||||
# coding=utf-8
|
||||
|
||||
import csv
|
||||
import struct
|
||||
import hashlib
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import csv
|
||||
from sys import version_info
|
||||
|
||||
number = 0
|
||||
value_len = 0
|
||||
buf = b''
|
||||
csv_dir = os.path.split(os.path.realpath(__file__))[0]
|
||||
csv_path = sys.argv[1] # 输入efuse.scv文件
|
||||
bin_path = sys.argv[2] # 输出efuse_cfg.bin烧写文件
|
||||
|
||||
def str_to_hex(s):
|
||||
return ' '.join([hex(ord(c)).replace('0x', '') for c in s])
|
||||
|
||||
def print_bytes(bytes):
|
||||
if version_info.major == 3:
|
||||
c = bytes.hex()
|
||||
print(c)
|
||||
else:
|
||||
c = bytes.encode('hex')
|
||||
print(c)
|
||||
|
||||
def get_flash_key_param():
|
||||
cfg_file = os.path.join(csv_dir, 'config', 'sign', 'encry_config.cfg')
|
||||
file1 = open(cfg_file)
|
||||
omrk1=""
|
||||
for line in file1:
|
||||
rs = re.search("Omrk1=", line)
|
||||
if rs:
|
||||
omrk1 = line[6:-1]
|
||||
if omrk1 == "":
|
||||
raise Exception("ERR: get_flash_key_param err, omrk1 is null", cfg_file)
|
||||
result = ""
|
||||
for i in range(0, len(omrk1), 4):
|
||||
result += (" " + omrk1[i:i+4])
|
||||
line = ''.join(result[1:].split(" ")[::-1])
|
||||
result = ""
|
||||
for i in range(0, len(line), 8):
|
||||
result += (" 0x" + line[i+4:i+8] + line[i:i+4])
|
||||
file1.close()
|
||||
return result[1:]
|
||||
|
||||
def get_root_key_hash():
|
||||
cfg_file = os.path.join(csv_dir, 'config', 'sign', 'root_pubk.bin.hash')
|
||||
file1 = open(cfg_file)
|
||||
line = file1.readline()
|
||||
if line == "":
|
||||
raise Exception("ERR: get_root_key_hash err, hash is null", cfg_file)
|
||||
result = ""
|
||||
for i in range(0, len(line), 8):
|
||||
result += (" 0x" + line[i+6:i+8] + line[i+4:i+6] + line[i+2:i+4] + line[i:i+2])
|
||||
file1.close()
|
||||
return result[1:]
|
||||
|
||||
def del_old_csv_key():
|
||||
with open(csv_path, 'r') as file1:
|
||||
lines = list(csv.reader(file1))
|
||||
for line in lines[::-1]:
|
||||
if 'sec_verify_enable' in line:
|
||||
lines.remove(line)
|
||||
elif 'otp_oem_mrk' in line:
|
||||
lines.remove(line)
|
||||
elif 'root_key_hash' in line:
|
||||
lines.remove(line)
|
||||
with open(csv_path, 'w') as file2:
|
||||
writer = csv.writer(file2)
|
||||
writer.writerows(lines)
|
||||
|
||||
def read_cfg_value(cfg_file, key):
|
||||
with open(cfg_file) as f:
|
||||
for line in f:
|
||||
if not line.startswith('#') and '=' in line:
|
||||
k, v = line.split('=')
|
||||
if k.strip() == key:
|
||||
return v.strip()
|
||||
return None
|
||||
|
||||
def set_new_csv_key():
|
||||
efuse_file = open(csv_path, 'a+', newline='')
|
||||
cfg_file = os.path.join(csv_dir, 'config', 'sign', 'root_pubk.bin.hash')
|
||||
# 安全启动开关&根公钥hash
|
||||
if os.path.exists(cfg_file):
|
||||
sec_en = "\n1,sec_verify_enable,960,1,0x1,PG0"
|
||||
root_key_hash = "\n1,root_key_hash,672,256,", get_root_key_hash() ,",PG5"
|
||||
efuse_file.writelines(sec_en)
|
||||
efuse_file.writelines(root_key_hash)
|
||||
|
||||
cfg_file = os.path.join(csv_dir, 'config', 'sign', 'liteos_app_bin_ecc.cfg')
|
||||
encry_en = read_cfg_value(cfg_file, 'SignSuite')
|
||||
PlainKey = read_cfg_value(cfg_file, 'PlainKey')
|
||||
demo = '8ABDA082DB74753577FF2D1E7D79DAC7'
|
||||
# flash加密秘钥
|
||||
if encry_en == '1' and PlainKey != demo:
|
||||
flash_key = "\n1,otp_oem_mrk,352,128,", get_flash_key_param() ,",PG3"
|
||||
efuse_file.writelines(flash_key)
|
||||
efuse_file.close()
|
||||
|
||||
def del_null_rows():
|
||||
with open(csv_path, 'r') as file1:
|
||||
reader = csv.reader(file1)
|
||||
rows = [row for row in reader]
|
||||
rows = [row for row in rows if any(row)]
|
||||
with open(csv_path, 'w', newline='') as file2:
|
||||
writer = csv.writer(file2)
|
||||
writer.writerows(rows)
|
||||
|
||||
def set_key_to_efuse():
|
||||
if os.path.exists(csv_path):
|
||||
del_old_csv_key()
|
||||
set_new_csv_key()
|
||||
del_null_rows()
|
||||
|
||||
# 配置秘钥到efuse.csv文件中
|
||||
set_key_to_efuse()
|
||||
|
||||
# 用reader读取csv文件
|
||||
#Use the reader to read the CSV file.
|
||||
with open(csv_path, 'r') as csvFile:
|
||||
reader = csv.reader(csvFile)
|
||||
for line in reader:
|
||||
if line and line[0] == "1":
|
||||
size = int(line[3])
|
||||
if (size <= 32):
|
||||
value_len = 4
|
||||
elif (size <= 64):
|
||||
value_len = 8
|
||||
else:
|
||||
value_len = size // 8
|
||||
result = struct.pack('BBHHH', 0, 8, int(line[2]), size, value_len)
|
||||
value_str = line[4]
|
||||
value_list = value_str.split(" ")
|
||||
value_struct = b''
|
||||
for i in range(value_len // 4):
|
||||
value = int(value_list[i], 16)
|
||||
value_struct = value_struct + struct.pack('I', value)
|
||||
print_bytes(value_struct)
|
||||
buf = buf + result + value_struct
|
||||
number = number + 1
|
||||
header = struct.pack('BBHIII', 0, 48, number, len(buf) + 48, 0, 0)
|
||||
data = header + buf
|
||||
data_len = len(data)
|
||||
print("data size: ", data_len)
|
||||
if data_len % 64 != 0:
|
||||
max_size = int((data_len / 64)+1) * 64
|
||||
if data_len < max_size:
|
||||
data = data + bytes([0] * int(max_size - data_len))
|
||||
print("finally size: ", len(data))
|
||||
|
||||
hash = hashlib.sha256(data).digest()
|
||||
bin_data = hash + data
|
||||
#print(bin_data)
|
||||
|
||||
with open(bin_path, 'wb+') as f:
|
||||
f.write(bin_data)
|
196
build/config/target_config/ws63/sign_encry/encryptandsign.sh
Executable file
196
build/config/target_config/ws63/sign_encry/encryptandsign.sh
Executable file
@ -0,0 +1,196 @@
|
||||
#!/bin/sh
|
||||
|
||||
CUR_DIR=$(cd $(dirname $0);pwd)
|
||||
|
||||
# 签名工具
|
||||
SIGN_TOOL=${CUR_DIR}/sign_tool_pltuni
|
||||
PACK_TOOL=${CUR_DIR}/packet_allinone.py
|
||||
EFUSE_TOOL=${CUR_DIR}/efuse_cfg_gen.py
|
||||
|
||||
# 默认入参
|
||||
INPUT_FILE=${1-"./input/pktbin.zip"}
|
||||
OUT_PATH=${2-"./output"}
|
||||
IMG_TYPE=${3-"all"}
|
||||
EXTERN_PARAM=${4-"none"}
|
||||
|
||||
# 配置文件
|
||||
TMP_DIR="${OUT_PATH}/tmp"
|
||||
CONF_DIR="${CUR_DIR}/config"
|
||||
SIGN_CONF_DIR="${CUR_DIR}/config/sign"
|
||||
|
||||
set_opt()
|
||||
{
|
||||
local tmp=$2
|
||||
tmp=${tmp//\//\\\/}
|
||||
sed -r -i "s/$1=.*/$1=$tmp/g" $3
|
||||
}
|
||||
|
||||
update_keyfile_path()
|
||||
{
|
||||
local file=$1
|
||||
local root_keyfile=`sed '/^RootKeyFile=/!d;s/.*=//' ${file}`
|
||||
local sub_keyfile=`sed '/^SubKeyFile=/!d;s/.*=//' ${file}`
|
||||
set_opt RootKeyFile ${SIGN_CONF_DIR}/${root_keyfile} $file
|
||||
set_opt SubKeyFile ${SIGN_CONF_DIR}/${sub_keyfile} $file
|
||||
}
|
||||
|
||||
# 镜像签名
|
||||
sign_image()
|
||||
{
|
||||
local config_name=$1
|
||||
local image_name=$2
|
||||
local src_config=${SIGN_CONF_DIR}/${config_name}
|
||||
local dst_config=${TMP_DIR}/${config_name}
|
||||
local src_image=${TMP_DIR}/${image_name}
|
||||
local dst_image=${TMP_DIR}/`basename ${image_name} .bin`_sign.bin
|
||||
local tmp_image=${TMP_DIR}/${image_name}_64B
|
||||
local image_size=`wc -c < ${src_image}`
|
||||
local cnt=`expr ${image_size} / 64 + 1`
|
||||
|
||||
echo "Start sign ${src_image} by ${config} ${image_size}"
|
||||
# 1.镜像64bye对齐
|
||||
dd if=${src_image} of=${tmp_image} bs=64c seek=0 count=${cnt} conv=sync
|
||||
mv ${tmp_image} ${src_image}
|
||||
# 2.准备签名配置文件
|
||||
cp ${src_config} ${dst_config}
|
||||
set_opt SrcFile ${src_image} ${dst_config}
|
||||
set_opt DstFile ${dst_image} ${dst_config}
|
||||
update_keyfile_path ${dst_config}
|
||||
|
||||
${SIGN_TOOL} 0 ${dst_config}
|
||||
rm -rf ${src_image}
|
||||
echo "Sign ${src_image} successful!!!"
|
||||
}
|
||||
|
||||
# 制作根公钥
|
||||
make_root_puk()
|
||||
{
|
||||
local config_name=$1
|
||||
local puk_name=$2
|
||||
local image_name=$3
|
||||
local src_config=${SIGN_CONF_DIR}/${config_name}
|
||||
local dst_config=${TMP_DIR}/${config_name}
|
||||
local puk_image=${TMP_DIR}/${puk_name}
|
||||
|
||||
# 1.制作根公钥
|
||||
cp ${src_config} ${dst_config}
|
||||
set_opt DstFile ${puk_image} ${dst_config}
|
||||
set_opt SrcFile ${SIGN_CONF_DIR}/ec_bp256_oem_root_private_key.pem ${dst_config}
|
||||
$SIGN_TOOL 1 ${dst_config}
|
||||
mv ${TMP_DIR}/root_pubk.bin.hash ${CONF_DIR}/sign/root_pubk.bin.hash
|
||||
# 2.将根公钥放到指定镜像头中
|
||||
cat ${puk_image} ${TMP_DIR}/${image_name} > ${TMP_DIR}/root_`basename ${image_name}`
|
||||
rm -f ${TMP_DIR}/${image_name}
|
||||
rm -f ${puk_image}
|
||||
}
|
||||
|
||||
make_burn_image()
|
||||
{
|
||||
local src_image=$1
|
||||
local dst_image=$2
|
||||
cp ${TMP_DIR}/${src_image} ${OUT_PATH}/${dst_image}
|
||||
}
|
||||
|
||||
get_ota_images()
|
||||
{
|
||||
local FILE_DIR=${TMP_DIR}
|
||||
local FILES=$(ls $FILE_DIR)
|
||||
for filename in $FILES
|
||||
do
|
||||
case $filename in
|
||||
*"test"*)
|
||||
image[IDX++]="test"
|
||||
;;
|
||||
*"app"*)
|
||||
image[IDX++]="app"
|
||||
;;
|
||||
*"boot"*)
|
||||
image[IDX++]="boot"
|
||||
;;
|
||||
*"nv"*)
|
||||
image[IDX++]="nv"
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
OTA_IMAGES=$(IFS=,; echo "${image[*]}")
|
||||
echo $OTA_IMAGES
|
||||
}
|
||||
|
||||
# 入参检查
|
||||
check_input()
|
||||
{
|
||||
echo "INPUT_FILE: ${INPUT_FILE}"
|
||||
echo "OUT_PATH: ${OUT_PATH}"
|
||||
echo "IMG_TYPE: ${IMG_TYPE}"
|
||||
|
||||
# 入参判断
|
||||
if [ ! -e ${INPUT_FILE} ]
|
||||
then
|
||||
echo "The input file ${INPUT_FILE} not exist, and exit!!!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d ${OUT_PATH} ]
|
||||
then
|
||||
echo "The output path ${OUT_PATH} not exist, and exit!!!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
#################### Main ####################
|
||||
|
||||
check_input
|
||||
rm -rf $TMP_DIR
|
||||
mkdir $TMP_DIR
|
||||
case ${IMG_TYPE} in
|
||||
*"ota"*)
|
||||
cp ${INPUT_FILE} ${OUT_PATH}/all.zip
|
||||
tar -vxf ${OUT_PATH}/all.zip -C ${TMP_DIR}
|
||||
rm ${OUT_PATH}/all.zip
|
||||
OTA_IMAGES=`get_ota_images`
|
||||
if [[ $OTA_IMAGES == *"app"* ]]; then
|
||||
sign_image liteos_app_bin_ecc_ota.cfg ws63-liteos-app.bin
|
||||
fi
|
||||
if [[ $OTA_IMAGES == *"boot"* ]]; then
|
||||
sign_image flash_bin_ecc.cfg flashboot.bin
|
||||
fi
|
||||
python3 ${CUR_DIR}/build_ota_pkt.py --path=${TMP_DIR},${OUT_PATH} --pkt=$OTA_IMAGES
|
||||
;;
|
||||
*"all"*)
|
||||
cp ${INPUT_FILE} ${OUT_PATH}/all.zip
|
||||
tar -xf ${OUT_PATH}/all.zip --strip-components 2 -C ${TMP_DIR}
|
||||
rm ${OUT_PATH}/all.zip
|
||||
# loaderboot
|
||||
sign_image loaderboot_bin_ecc.cfg loaderboot.bin
|
||||
make_root_puk root_pubk.cfg root_pubk.bin loaderboot_sign.bin
|
||||
# param
|
||||
sign_image param_bin_ecc.cfg params.bin
|
||||
make_root_puk root_pubk.cfg root_pubk.bin params_sign.bin
|
||||
# ssb
|
||||
sign_image ssb_bin_ecc.cfg ssb.bin
|
||||
# flashboot
|
||||
cp ${TMP_DIR}/flashboot.bin ${TMP_DIR}/flashboot_backup.bin
|
||||
sign_image flash_bin_ecc.cfg flashboot.bin
|
||||
# flashboot backup
|
||||
sign_image flash_backup_bin_ecc.cfg flashboot_backup.bin
|
||||
# app
|
||||
sign_image liteos_app_bin_ecc.cfg ws63-liteos-app.bin
|
||||
# mfg
|
||||
if [ -d "${TMP_DIR}/ws63-liteos-mfg.bin" ];then
|
||||
sign_image liteos_mfg_bin_ecc.cfg ws63-liteos-mfg.bin
|
||||
fi
|
||||
# efuse
|
||||
$EFUSE_TOOL ${TMP_DIR}/efuse.csv ${TMP_DIR}/efuse_cfg.bin
|
||||
# 打包
|
||||
python3 $PACK_TOOL $TMP_DIR $EXTERN_PARAM
|
||||
# 整包fwpkg镜像加密 & 模块烧写文件
|
||||
make_burn_image ws63-liteos-app_all.fwpkg ws63-liteos-app_encry.fwpkg
|
||||
;;
|
||||
*)
|
||||
echo "Unknown image type: ${IMG_TYPE}"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
rm -rf $TMP_DIR
|
84
build/config/target_config/ws63/sign_encry/gen_all_key.sh
Executable file
84
build/config/target_config/ws63/sign_encry/gen_all_key.sh
Executable file
@ -0,0 +1,84 @@
|
||||
#!/bin/bash
|
||||
SIGN_CONF_DIR=./config/sign
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
param="all"
|
||||
else
|
||||
param=$1
|
||||
fi
|
||||
|
||||
if [ -f $SIGN_CONF_DIR"/ec_bp256_oem_root_private_key.pem" ]; then
|
||||
echo "WARNING: The old keys will be overwritten, and new keys can not work on old devices. Continue? (Y/N)"
|
||||
read confirm
|
||||
if [[ $confirm != Y ]] && [[ $confirm != y ]]; then
|
||||
exit
|
||||
else
|
||||
chmod 755 ./* -R
|
||||
fi
|
||||
fi
|
||||
|
||||
# =======================安全启动: 随机生成签名私钥 & 根公钥 ==============================================
|
||||
if [[ $param == sec ]] || [[ $param == all ]]; then
|
||||
# 生成根私钥/公钥
|
||||
openssl ecparam -genkey -name brainpoolP256r1 -out $SIGN_CONF_DIR"/ec_bp256_oem_root_private_key.pem"
|
||||
openssl ec -in $SIGN_CONF_DIR"/ec_bp256_oem_root_private_key.pem" -pubout -out $SIGN_CONF_DIR"/ec_bp256_oem_root_public_key.pem"
|
||||
# 生成ssb私钥
|
||||
openssl ecparam -genkey -name brainpoolP256r1 -out $SIGN_CONF_DIR"/ec_bp256_ssb_private_key.pem"
|
||||
# 生成flashboot私钥
|
||||
openssl ecparam -genkey -name brainpoolP256r1 -out $SIGN_CONF_DIR"/ec_bp256_flashboot_private_key.pem"
|
||||
# 生成flashboot_backup私钥
|
||||
openssl ecparam -genkey -name brainpoolP256r1 -out $SIGN_CONF_DIR"/ec_bp256_flashboot_backup_private_key.pem"
|
||||
# 生成loaderboot私钥
|
||||
openssl ecparam -genkey -name brainpoolP256r1 -out $SIGN_CONF_DIR"/ec_bp256_loaderboot_private_key.pem"
|
||||
# 生成param私钥
|
||||
openssl ecparam -genkey -name brainpoolP256r1 -out $SIGN_CONF_DIR"/ec_bp256_param_private_key.pem"
|
||||
# 生成app私钥
|
||||
openssl ecparam -genkey -name brainpoolP256r1 -out $SIGN_CONF_DIR"/ec_bp256_app_private_key.pem"
|
||||
fi
|
||||
|
||||
# =======================Flash在线解密: 随机生成派生参数, 派生flash秘钥 ======================================
|
||||
if [[ $param == encry ]] || [[ $param == all ]]; then
|
||||
ENCRY_CONF=./config/sign/liteos_app_bin_ecc.cfg
|
||||
OTA_ENCRY_CONF=./config/sign/liteos_app_bin_ecc_ota.cfg
|
||||
OTA_CONF=./config/ota/fota_template.cfg
|
||||
MAKE_KEY_CONF=./config/sign/encry_config.cfg
|
||||
MAKE_KEY_TOOL=./tool_security
|
||||
random_num() { < /dev/urandom tr -dc A-F0-9 | head -c $1; echo;}
|
||||
set_opt() { sed -r -i "s/$1=.*/$1=$2/g" $3; }
|
||||
|
||||
# 1. 随机生成派生参数
|
||||
PARAM_OMRK1=`random_num 32`
|
||||
PARAM_OKPSALT=`random_num 64`
|
||||
PARAM_OWNERID=0
|
||||
|
||||
echo "Omrk1 =$PARAM_OMRK1"
|
||||
echo "OkpSalt=${PARAM_OKPSALT:0:56}"
|
||||
echo "OwnerId=$PARAM_OWNERID"
|
||||
|
||||
# 2.配置派生参数到配置文件encry_config.cfg, 该文件为flash加密秘钥派生参数
|
||||
set_opt Omrk1 $PARAM_OMRK1 $MAKE_KEY_CONF
|
||||
set_opt OkpSalt ${PARAM_OKPSALT:0:56} $MAKE_KEY_CONF
|
||||
set_opt OwnerId $PARAM_OWNERID $MAKE_KEY_CONF
|
||||
|
||||
# 3.派生flash秘钥odrk & 配置秘钥到配置文件liteos_app_bin_ecc.cfg
|
||||
PARAM_ENCRY_IV=`random_num 32`
|
||||
PARAM_ENCRY_KEY=`$MAKE_KEY_TOOL 0 $MAKE_KEY_CONF | tr -cd "[0-9A-Z]"`
|
||||
set_opt PlainKey ${PARAM_ENCRY_KEY:5:32} $ENCRY_CONF
|
||||
echo "odrk:${PARAM_ENCRY_KEY:5}"
|
||||
set_opt Iv $PARAM_ENCRY_IV $ENCRY_CONF
|
||||
set_opt ProtectionKeyL1 ${PARAM_OKPSALT:0:32} $ENCRY_CONF
|
||||
set_opt ProtectionKeyL2 ${PARAM_OKPSALT:32:64} $ENCRY_CONF
|
||||
|
||||
set_opt PlainKey ${PARAM_ENCRY_KEY:5:32} $OTA_ENCRY_CONF
|
||||
set_opt Iv $PARAM_ENCRY_IV $OTA_ENCRY_CONF
|
||||
set_opt ProtectionKeyL1 ${PARAM_OKPSALT:0:32} $OTA_ENCRY_CONF
|
||||
set_opt ProtectionKeyL2 ${PARAM_OKPSALT:32:64} $OTA_ENCRY_CONF
|
||||
|
||||
# 4.派生ota升级加密秘钥abrk & 配置秘钥到配置文件fota_template.cfg
|
||||
PARAM_ENCRY_KEY=`$MAKE_KEY_TOOL 1 $MAKE_KEY_CONF | tr -cd "[0-9A-Z]"`
|
||||
set_opt PlainKey ${PARAM_ENCRY_KEY:5:32} $OTA_CONF
|
||||
echo "abrk:${PARAM_ENCRY_KEY:5}"
|
||||
set_opt Iv $PARAM_ENCRY_IV $OTA_CONF
|
||||
set_opt ProtectionKeyL1 ${PARAM_OKPSALT:0:32} $OTA_CONF
|
||||
set_opt ProtectionKeyL2 ${PARAM_OKPSALT:32:64} $OTA_CONF
|
||||
fi
|
BIN
build/config/target_config/ws63/sign_encry/lzma_tool
Executable file
BIN
build/config/target_config/ws63/sign_encry/lzma_tool
Executable file
Binary file not shown.
77
build/config/target_config/ws63/sign_encry/packet_allinone.py
Executable file
77
build/config/target_config/ws63/sign_encry/packet_allinone.py
Executable file
@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
# encoding=utf-8
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
from typing import List
|
||||
from packet_create import packet_bin
|
||||
|
||||
def get_file_size(file_path: str)->int:
|
||||
try:
|
||||
return os.stat(file_path).st_size
|
||||
except BaseException as e:
|
||||
print(e)
|
||||
exit(-1)
|
||||
|
||||
# ws63
|
||||
def make_all_in_one_packet(argv):
|
||||
fwpkg_dir = argv[1]
|
||||
extr_defines = argv[2]
|
||||
|
||||
# loader boot
|
||||
loadboot_bin = os.path.join(fwpkg_dir, "root_loaderboot_sign.bin")
|
||||
loadboot_bx = loadboot_bin + "|0x0|0x200000|0"
|
||||
# efuse bin
|
||||
efuse_bin = os.path.join(fwpkg_dir, "efuse_cfg.bin")
|
||||
efuse_bx = efuse_bin + "|0x0|0x200000|3"
|
||||
# params
|
||||
params_bin = os.path.join(fwpkg_dir, "root_params_sign.bin")
|
||||
params_bx = params_bin + f"|0x200000|{hex(get_file_size(params_bin))}|1"
|
||||
# ssb
|
||||
ssb_bin = os.path.join(fwpkg_dir, "ssb_sign.bin")
|
||||
ssb_bx = ssb_bin + f"|0x202000|{hex(get_file_size(ssb_bin))}|1"
|
||||
# flash boot
|
||||
flashboot_bin = os.path.join(fwpkg_dir, "flashboot_sign.bin")
|
||||
flashboot_bx = flashboot_bin + f"|0x220000|{hex(get_file_size(flashboot_bin))}|1"
|
||||
# flash boot backup
|
||||
flashboot_backup_bin = os.path.join(fwpkg_dir, "flashboot_backup_sign.bin")
|
||||
flashboot_backup_bx = flashboot_backup_bin + f"|0x210000|{hex(get_file_size(flashboot_backup_bin))}|1"
|
||||
# nv
|
||||
nv_bin = os.path.join(fwpkg_dir, "ws63_all_nv.bin")
|
||||
nv_bx = nv_bin + f"|0x5FC000|0x4000|1"
|
||||
# nv backup
|
||||
nv_backup_bin = os.path.join(fwpkg_dir, "ws63_all_nv_factory.bin")
|
||||
nv_backup_bx = nv_backup_bin + f"|0x20C000|0x4000|1"
|
||||
# app
|
||||
app_bin = os.path.join(fwpkg_dir, "ws63-liteos-app_sign.bin")
|
||||
app_bx = app_bin + f"|0x230000|{hex(get_file_size(app_bin))}|1"
|
||||
# mfg
|
||||
mfg_bin = os.path.join(fwpkg_dir, "ws63-liteos-mfg_sign.bin")
|
||||
|
||||
packet_post_agvs = list()
|
||||
packet_post_agvs.append(loadboot_bx)
|
||||
packet_post_agvs.append(params_bx)
|
||||
packet_post_agvs.append(ssb_bx)
|
||||
packet_post_agvs.append(flashboot_bx)
|
||||
packet_post_agvs.append(flashboot_backup_bx)
|
||||
packet_post_agvs.append(nv_bx)
|
||||
if "PACKET_NV_FACTORY" in extr_defines:
|
||||
print("nv factory pack")
|
||||
packet_post_agvs.append(nv_backup_bx)
|
||||
packet_post_agvs.append(app_bx)
|
||||
if os.path.exists(mfg_bin):
|
||||
mfg_bx = mfg_bin + f"|0x470000|{hex(0x183000)}|1"
|
||||
packet_post_agvs.append(mfg_bx)
|
||||
packet_post_agvs.append(efuse_bx)
|
||||
fpga_fwpkg = os.path.join(fwpkg_dir, f"ws63-liteos-app_all.fwpkg")
|
||||
packet_bin(fpga_fwpkg, packet_post_agvs)
|
||||
|
||||
packet_post_agvs = list()
|
||||
packet_post_agvs.append(loadboot_bx)
|
||||
packet_post_agvs.append(app_bx)
|
||||
fpga_loadapp_only_fwpkg = os.path.join(fwpkg_dir, f"ws63-liteos-app_only.fwpkg")
|
||||
packet_bin(fpga_loadapp_only_fwpkg, packet_post_agvs)
|
||||
|
||||
if __name__ == '__main__':
|
||||
make_all_in_one_packet(sys.argv)
|
411
build/config/target_config/ws63/sign_encry/packet_create.py
Executable file
411
build/config/target_config/ws63/sign_encry/packet_create.py
Executable file
@ -0,0 +1,411 @@
|
||||
#!/usr/bin/env python3
|
||||
# encoding=utf-8
|
||||
|
||||
import struct
|
||||
import sys
|
||||
import os
|
||||
import hashlib
|
||||
# only use for nbiot
|
||||
|
||||
class crc16:
|
||||
POLYNOMIAL = 0x1021
|
||||
PRESET = 0x0000
|
||||
_tab = []
|
||||
def __init__(self):
|
||||
self._tab = [self._initial(i) for i in range(256)]
|
||||
|
||||
def _initial(self, c):
|
||||
crc = 0
|
||||
c = c << 8
|
||||
for j in range(8):
|
||||
if (crc ^ c) & 0x8000:
|
||||
crc = (crc << 1) ^ self.POLYNOMIAL
|
||||
else:
|
||||
crc = crc << 1
|
||||
c = c << 1
|
||||
return crc
|
||||
|
||||
def _update_crc(self, crc, c):
|
||||
cc = 0xff & int(c)
|
||||
|
||||
tmp = (crc >> 8) ^ cc
|
||||
crc = (crc << 8) ^ self._tab[tmp & 0xff]
|
||||
crc = crc & 0xffff
|
||||
|
||||
return crc
|
||||
|
||||
def crc(self, str):
|
||||
crc = self.PRESET
|
||||
for c in str:
|
||||
crc = self._update_crc(crc, ord(c))
|
||||
return crc
|
||||
|
||||
def crcb(self, i):
|
||||
crc = self.PRESET
|
||||
for c in i:
|
||||
crc = self._update_crc(crc, c)
|
||||
return crc
|
||||
|
||||
t = crc16()
|
||||
ignoreFlag = 1
|
||||
def parse_param(pathNameListNew, burnAddrListNew, burnSizeListNew, imageSizeListNew, typeListNew, inputList):
|
||||
for item in inputList:
|
||||
if '|' in item:
|
||||
path, burnAddr, burnSize, type = item.split("|")
|
||||
if ignoreFlag == 1 and not os.path.exists(path):
|
||||
continue
|
||||
imageSize = os.path.getsize(path)
|
||||
pathNameListNew.append(path)
|
||||
burnAddrListNew.append(int(burnAddr, 16))
|
||||
burnSizeListNew.append(int(burnSize, 16))
|
||||
imageSizeListNew.append(imageSize)
|
||||
typeListNew.append(int(type))
|
||||
else:
|
||||
pathNameListNew.append(item)
|
||||
imageSize = os.path.getsize(item)
|
||||
imageSizeListNew.append(imageSize)
|
||||
|
||||
def create_sha_file(source, target):
|
||||
for src in source:
|
||||
with open(src, "rb" ) as bin_file:
|
||||
sha = hashlib.sha256( bin_file.read() )
|
||||
bin_file.close()
|
||||
with open( str(target), "wb") as sha_file:
|
||||
sha_file.write( sha.digest())
|
||||
|
||||
def create_allinone(pathNameList, burnAddrList, burnSizeList, imageSizeList, typeList, fileInfoList, outputPath):
|
||||
flag = 0xefbeaddf
|
||||
crc = 0
|
||||
imageNum = len(pathNameList)
|
||||
# sizeof(IMAGE_INFO) is 52, sizeof(FWPKG_HEAD) is 12
|
||||
headLen = imageNum * 52 + 12
|
||||
# each image has 16byte 0 in the end
|
||||
padLen = 16 * imageNum
|
||||
totalFileSize = sum(imageSizeList) + headLen + padLen
|
||||
# prepare
|
||||
outputRoot = os.path.dirname(outputPath)
|
||||
if not os.path.isdir(outputRoot):
|
||||
os.makedirs(outputRoot)
|
||||
with open(outputPath, 'wb+') as file:
|
||||
file.write(struct.pack('IHHI', flag, crc, imageNum, totalFileSize))
|
||||
startIndex = headLen
|
||||
times = 0
|
||||
for path in pathNameList:
|
||||
pathName = os.path.basename(path)
|
||||
file.write(
|
||||
struct.pack('32sIIIII', bytes(pathName, 'ascii'), startIndex, imageSizeList[times], burnAddrList[times],
|
||||
burnSizeList[times], typeList[times]))
|
||||
# separate each image with 16 bytes 0
|
||||
startIndex = startIndex + imageSizeList[times] + 16
|
||||
times += 1
|
||||
|
||||
for info in fileInfoList:
|
||||
file.write(info)
|
||||
file.write(struct.pack('IIII', 0, 0, 0, 0))
|
||||
|
||||
file.flush()
|
||||
# crc range is FWPKG_HEAD.imageNum to end, begin index is 6bytes
|
||||
file.seek(6)
|
||||
newdata = file.read(headLen - 6)
|
||||
crc16 = t.crcb(newdata)
|
||||
file.seek(4)
|
||||
file.write(struct.pack('H', crc16))
|
||||
file.close()
|
||||
def parse_allinone(pathNameList, burnAddrList, burnSizeList, imageSizeList, typeList, startIndexList, fileInfoList, packet_path):
|
||||
with open(packet_path, 'rb+') as file:
|
||||
info = file.read(struct.calcsize('IHHI'))
|
||||
flag, crc, imageNum, totalFileSize = struct.unpack('IHHI', info)
|
||||
times = 0
|
||||
for index in range(0, imageNum):
|
||||
info = file.read(struct.calcsize('32sIIIII'))
|
||||
pathName, startIndex, imageSize, burnAddr, burnSize, type2 = struct.unpack('32sIIIII', info)
|
||||
#separate each image with 16 bytes 0
|
||||
pathName = str(pathName, encoding="utf-8")
|
||||
pathNameNew = ''
|
||||
for char in pathName:
|
||||
if char != '\x00':
|
||||
pathNameNew += char
|
||||
print(pathNameNew)
|
||||
pathNameList.append(pathNameNew)
|
||||
startIndexList.append(startIndex)
|
||||
burnAddrList.append(burnAddr)
|
||||
burnSizeList.append(burnSize)
|
||||
imageSizeList.append(imageSize)
|
||||
typeList.append(type2)
|
||||
|
||||
for index in range(0, imageNum):
|
||||
file.seek(startIndexList[index])
|
||||
fileInfoList.append(file.read(imageSizeList[index]))
|
||||
file.close()
|
||||
|
||||
def packet_bin(outputPath, inputList):
|
||||
pathNameList = []
|
||||
burnAddrList = []
|
||||
burnSizeList = []
|
||||
imageSizeList = []
|
||||
typeList = []
|
||||
fileInfoList = []
|
||||
parse_param(pathNameList, burnAddrList, burnSizeList, imageSizeList, typeList, inputList)
|
||||
for path in pathNameList:
|
||||
with open(path, 'rb+') as subfile:
|
||||
data = subfile.read()
|
||||
fileInfoList.append(data)
|
||||
subfile.close()
|
||||
print(pathNameList)
|
||||
print(burnAddrList)
|
||||
print(burnSizeList)
|
||||
print(imageSizeList)
|
||||
print(typeList)
|
||||
|
||||
create_allinone(pathNameList, burnAddrList, burnSizeList, imageSizeList, typeList, fileInfoList, outputPath)
|
||||
def update_bin(packet_path, inputList):
|
||||
pathNameList = []
|
||||
burnAddrList = []
|
||||
burnSizeList = []
|
||||
imageSizeList = []
|
||||
typeList = []
|
||||
startIndexList = []
|
||||
fileInfoList = []
|
||||
|
||||
pathNameListNew = []
|
||||
burnAddrListNew = []
|
||||
burnSizeListNew = []
|
||||
imageSizeListNew = []
|
||||
typeListNew = []
|
||||
parse_param(pathNameListNew, burnAddrListNew, burnSizeListNew, imageSizeListNew, typeListNew, inputList)
|
||||
parse_allinone(pathNameList, burnAddrList, burnSizeList, imageSizeList, typeList, startIndexList, fileInfoList,
|
||||
packet_path)
|
||||
|
||||
for index in range(0, len(pathNameListNew)):
|
||||
pathNew = pathNameListNew[index]
|
||||
print(os.path.basename(pathNew))
|
||||
pathIn32Byte = os.path.basename(pathNew)
|
||||
if len(pathIn32Byte) > 32:
|
||||
pathIn32Byte = pathIn32Byte[0:32]
|
||||
if pathIn32Byte in pathNameList:
|
||||
for index2 in range(0, len(pathNameList)):
|
||||
path = pathNameList[index2]
|
||||
if path == pathIn32Byte:
|
||||
with open(pathNew, 'rb+') as subfile:
|
||||
fileInfoList[index2] = subfile.read()
|
||||
pathNameList[index2] = os.path.basename(pathNew)
|
||||
if len(burnAddrListNew) > index:
|
||||
burnAddrList[index2] = burnAddrListNew[index]
|
||||
if len(burnSizeListNew) > index:
|
||||
burnSizeList[index2] = burnSizeListNew[index]
|
||||
imageSizeList[index2] = imageSizeListNew[index]
|
||||
if len(typeListNew) > index:
|
||||
typeList[index2] = typeListNew[index]
|
||||
break
|
||||
else:
|
||||
pathNameList.append(pathNameListNew[index])
|
||||
burnAddrList.append(burnAddrListNew[index])
|
||||
burnSizeList.append(burnSizeListNew[index])
|
||||
imageSizeList.append(imageSizeListNew[index])
|
||||
typeList.append(typeListNew[index])
|
||||
with open(pathNew, 'rb+') as subfile:
|
||||
fileInfoList.append(subfile.read())
|
||||
print(pathNameList)
|
||||
print(burnAddrList)
|
||||
print(burnSizeList)
|
||||
print(imageSizeList)
|
||||
print(typeList)
|
||||
|
||||
create_allinone(pathNameList, burnAddrList, burnSizeList, imageSizeList, typeList, fileInfoList, packet_path)
|
||||
def delete_bin(packet_path, name_list):
|
||||
pathNameList = []
|
||||
burnAddrList = []
|
||||
burnSizeList = []
|
||||
imageSizeList = []
|
||||
typeList = []
|
||||
startIndexList = []
|
||||
fileInfoList = []
|
||||
|
||||
pathNameListNew = name_list
|
||||
|
||||
parse_allinone(pathNameList, burnAddrList, burnSizeList, imageSizeList, typeList, startIndexList, fileInfoList,
|
||||
packet_path)
|
||||
|
||||
for pathNew in pathNameListNew:
|
||||
print(os.path.basename(pathNew))
|
||||
pathIn32Byte = os.path.basename(pathNew)
|
||||
if len(pathIn32Byte) > 32:
|
||||
pathIn32Byte = pathIn32Byte[0:32]
|
||||
if pathIn32Byte in pathNameList:
|
||||
for index2 in range(0, len(pathNameList)):
|
||||
path = pathNameList[index2]
|
||||
if path == pathIn32Byte:
|
||||
del fileInfoList[index2]
|
||||
del pathNameList[index2]
|
||||
del burnAddrList[index2]
|
||||
del burnSizeList[index2]
|
||||
del imageSizeList[index2]
|
||||
del typeList[index2]
|
||||
break
|
||||
print(pathNameList)
|
||||
print(burnAddrList)
|
||||
print(burnSizeList)
|
||||
print(imageSizeList)
|
||||
print(typeList)
|
||||
|
||||
create_allinone(pathNameList, burnAddrList, burnSizeList, imageSizeList, typeList, fileInfoList, packet_path)
|
||||
def split_bin(packet_path, output_path):
|
||||
pathNameList = []
|
||||
burnAddrList = []
|
||||
burnSizeList = []
|
||||
imageSizeList = []
|
||||
typeList = []
|
||||
startIndexList = []
|
||||
fileInfoList = []
|
||||
|
||||
parse_allinone(pathNameList, burnAddrList, burnSizeList, imageSizeList, typeList, startIndexList, fileInfoList,
|
||||
packet_path)
|
||||
print(pathNameList)
|
||||
print(burnAddrList)
|
||||
print(burnSizeList)
|
||||
print(imageSizeList)
|
||||
print(typeList)
|
||||
|
||||
imageNum = len(pathNameList)
|
||||
for index in range(0, imageNum):
|
||||
pathName = os.path.join(output_path, pathNameList[index])
|
||||
print(pathName)
|
||||
with open(pathName, 'wb+') as file:
|
||||
file.write(fileInfoList[index])
|
||||
file.close()
|
||||
def show_bin(packet_path):
|
||||
pathNameList = []
|
||||
burnAddrList = []
|
||||
burnSizeList = []
|
||||
imageSizeList = []
|
||||
typeList = []
|
||||
startIndexList = []
|
||||
fileInfoList = []
|
||||
|
||||
parse_allinone(pathNameList, burnAddrList, burnSizeList, imageSizeList, typeList, startIndexList, fileInfoList,
|
||||
packet_path)
|
||||
print("pathNameList")
|
||||
print(pathNameList)
|
||||
print("burnAddrList")
|
||||
print(burnAddrList)
|
||||
print("burnSizeList")
|
||||
print(burnSizeList)
|
||||
print("imageSizeList")
|
||||
print(imageSizeList)
|
||||
print("typeList")
|
||||
print(typeList)
|
||||
'''
|
||||
def merge_bin(packet_path, inputList):
|
||||
pathNameList = []
|
||||
burnAddrList = []
|
||||
burnSizeList = []
|
||||
imageSizeList = []
|
||||
typeList = []
|
||||
startIndexList = []
|
||||
fileInfoList = []
|
||||
|
||||
parse_allinone(pathNameList, burnAddrList, burnSizeList, imageSizeList, typeList, startIndexList, fileInfoList,
|
||||
packet_path)
|
||||
|
||||
hasKvBin = False
|
||||
kvBinIndex = -1
|
||||
for typeItem in typeList:
|
||||
kvBinIndex += 1
|
||||
if typeItem == 2:
|
||||
hasKvBin = True
|
||||
break
|
||||
if hasKvBin is False:
|
||||
return
|
||||
pathNew = inputList[0]
|
||||
subfile = open(pathNew, 'rb+')
|
||||
newBinArray = subfile.read()
|
||||
subfile.close()
|
||||
newKv = kv_create.decode_kv_bin(bytearray(newBinArray))
|
||||
srcBinArray = fileInfoList[kvBinIndex]
|
||||
srcKv = kv_create.decode_kv_bin(bytearray(srcBinArray))
|
||||
srcKv[0xb0].update(newKv[0xb0])
|
||||
srcKv[0xb2].update(newKv[0xb2])
|
||||
srcKv[0xb4].update(newKv[0xb4])
|
||||
fileInfoList[kvBinIndex] = kv_create.get_kv_bin(srcKv)
|
||||
|
||||
print(pathNameList)
|
||||
print(burnAddrList)
|
||||
print(burnSizeList)
|
||||
print(imageSizeList)
|
||||
print(typeList)
|
||||
|
||||
create_allinone(pathNameList, burnAddrList, burnSizeList, imageSizeList, typeList, fileInfoList, packet_path)
|
||||
'''
|
||||
if __name__=="__main__":
|
||||
args = len(sys.argv)
|
||||
argv = sys.argv
|
||||
if(args <= 1):
|
||||
print("parma error, please use -help for usage")
|
||||
sys.exit()
|
||||
if (argv[1] == '-hard'):
|
||||
ignoreFlag = 0
|
||||
del argv[1]
|
||||
if (argv[1] == '-packet'):
|
||||
outputPath = argv[2]
|
||||
print(outputPath)
|
||||
del argv[2]
|
||||
del argv[1]
|
||||
del argv[0]
|
||||
packet_bin(outputPath, argv)
|
||||
elif (argv[1] == '-update'):
|
||||
outputPath = argv[2]
|
||||
print(outputPath)
|
||||
del argv[2]
|
||||
del argv[1]
|
||||
del argv[0]
|
||||
update_bin(outputPath, argv)
|
||||
elif (argv[1] == '-split'):
|
||||
input_file = argv[2]
|
||||
outputPath = argv[3]
|
||||
split_bin(input_file, outputPath)
|
||||
elif (argv[1] == '-show'):
|
||||
input_file = argv[2]
|
||||
show_bin(input_file)
|
||||
elif (argv[1] == '-delete'):
|
||||
outputPath = argv[2]
|
||||
print(outputPath)
|
||||
del argv[2]
|
||||
del argv[1]
|
||||
del argv[0]
|
||||
delete_bin(outputPath, argv)
|
||||
elif (argv[1] == '-merge'):
|
||||
outputPath = argv[2]
|
||||
print(outputPath)
|
||||
del argv[2]
|
||||
del argv[1]
|
||||
del argv[0]
|
||||
merge_bin(outputPath, argv)
|
||||
elif (argv[1] == '-sha256'):
|
||||
outputPath = argv[2]
|
||||
print(outputPath)
|
||||
del argv[2]
|
||||
del argv[1]
|
||||
del argv[0]
|
||||
create_sha_file(argv, outputPath)
|
||||
elif (argv[1] == '-help'):
|
||||
print("\
|
||||
-packet, packet all bins as one\r\n\
|
||||
param should be : -packet \"outputfile\" \"binName1|burnAddr|burnSize|type\"...\r\n\
|
||||
-split, split inputefile as several bins\r\n\
|
||||
param should be : -split inputefile outputPath\r\n\
|
||||
-update, update bins in inputefile, if bin not in inputefile, it will be add.\r\n\
|
||||
param should be : -update \"inputefile\" \"binName1|burnAddr|burnSize|type\"...\r\n\
|
||||
-delete, delete bins in inputfile\r\n\
|
||||
param should be : -delete inputefile binName1 binName2...\r\n\
|
||||
-merge, merge kv bin in inputefile, if bin not in inputefile, it will be add.\r\n\
|
||||
param should be : -merge inputefile binName1...\r\n\
|
||||
-show, show the bins in inputfile\r\n\
|
||||
param should be : -show \"inputefile\"\r\n\
|
||||
-help\r\n")
|
||||
else:
|
||||
outputPath = argv[1]
|
||||
print(outputPath)
|
||||
del argv[1]
|
||||
del argv[0]
|
||||
packet_bin(outputPath, argv)
|
||||
|
BIN
build/config/target_config/ws63/sign_encry/sign_tool_pltuni
Executable file
BIN
build/config/target_config/ws63/sign_encry/sign_tool_pltuni
Executable file
Binary file not shown.
BIN
build/config/target_config/ws63/sign_encry/tool_security
Executable file
BIN
build/config/target_config/ws63/sign_encry/tool_security
Executable file
Binary file not shown.
Reference in New Issue
Block a user