140681896Sopenharmony_ci#!/usr/bin/env python3 240681896Sopenharmony_ci# -*- coding: utf-8 -*- 340681896Sopenharmony_ci 440681896Sopenharmony_ci# Copyright (c) 2022 Huawei Device Co., Ltd. 540681896Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 640681896Sopenharmony_ci# you may not use this file except in compliance with the License. 740681896Sopenharmony_ci# You may obtain a copy of the License at 840681896Sopenharmony_ci# 940681896Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 1040681896Sopenharmony_ci# 1140681896Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 1240681896Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 1340681896Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1440681896Sopenharmony_ci# See the License for the specific language governing permissions and 1540681896Sopenharmony_ci# limitations under the License. 1640681896Sopenharmony_ci""" 1740681896Sopenharmony_ciDescription : Generate the update.bin file 1840681896Sopenharmony_ci""" 1940681896Sopenharmony_ciimport os 2040681896Sopenharmony_ciimport struct 2140681896Sopenharmony_ciimport hashlib 2240681896Sopenharmony_ciimport subprocess 2340681896Sopenharmony_cifrom log_exception import UPDATE_LOGGER 2440681896Sopenharmony_cifrom utils import OPTIONS_MANAGER 2540681896Sopenharmony_cifrom create_hashdata import HashType 2640681896Sopenharmony_cifrom create_hashdata import CreateHash 2740681896Sopenharmony_cifrom create_hashdata import HASH_BLOCK_SIZE 2840681896Sopenharmony_cifrom cryptography.hazmat.primitives import serialization 2940681896Sopenharmony_cifrom cryptography.hazmat.primitives import hashes 3040681896Sopenharmony_cifrom cryptography.hazmat.backends import default_backend 3140681896Sopenharmony_cifrom cryptography.hazmat.primitives.asymmetric import padding 3240681896Sopenharmony_ci 3340681896Sopenharmony_ciUPGRADE_FILE_HEADER_LEN = 180 3440681896Sopenharmony_ciUPGRADE_RESERVE_LEN = 16 3540681896Sopenharmony_ciSIGN_SHA256_LEN = 256 3640681896Sopenharmony_ciSIGN_SHA384_LEN = 384 3740681896Sopenharmony_ciUPGRADE_SIGNATURE_LEN = SIGN_SHA256_LEN + SIGN_SHA384_LEN 3840681896Sopenharmony_ciTLV_SIZE = 4 3940681896Sopenharmony_ciUPGRADE_PKG_HEADER_SIZE = 136 4040681896Sopenharmony_ciUPGRADE_PKG_TIME_SIZE = 32 4140681896Sopenharmony_ciUPGRADE_COMPINFO_SIZE = 71 4240681896Sopenharmony_ciUPGRADE_COMPINFO_SIZE_L2 = 87 4340681896Sopenharmony_ciCOMPONENT_ADDR_SIZE = 16 4440681896Sopenharmony_ciCOMPONENT_ADDR_SIZE_L2 = 32 4540681896Sopenharmony_ciCOMPONENT_INFO_FMT_SIZE = 5 4640681896Sopenharmony_ciCOMPONENT_VERSION_SIZE = 10 4740681896Sopenharmony_ciCOMPONENT_SIZE_FMT_SIZE = 8 4840681896Sopenharmony_ciCOMPONENT_DIGEST_SIZE = 32 4940681896Sopenharmony_ciBLOCK_SIZE = 8192 5040681896Sopenharmony_ciHEADER_TLV_TYPE = 0x11 5140681896Sopenharmony_ciHEADER_TLV_TYPE_L2 = 0x01 5240681896Sopenharmony_ci# signature algorithm 5340681896Sopenharmony_ciSIGN_ALGO_RSA = "SHA256withRSA" 5440681896Sopenharmony_ciSIGN_ALGO_PSS = "SHA256withPSS" 5540681896Sopenharmony_ci 5640681896Sopenharmony_ci""" 5740681896Sopenharmony_ciFormat 5840681896Sopenharmony_ciH: unsigned short 5940681896Sopenharmony_ciI: unsigned int 6040681896Sopenharmony_ciB: unsigned char 6140681896Sopenharmony_cis: char[] 6240681896Sopenharmony_ci""" 6340681896Sopenharmony_ciTLV_FMT = "2H" 6440681896Sopenharmony_ciUPGRADE_PKG_HEADER_FMT = "2I64s64s" 6540681896Sopenharmony_ciUPGRADE_PKG_TIME_FMT = "16s16s" 6640681896Sopenharmony_ciCOMPONENT_INFO_FMT = "H3B" 6740681896Sopenharmony_ciCOMPONENT_SIZE_FMT = "iI" 6840681896Sopenharmony_ci 6940681896Sopenharmony_ci 7040681896Sopenharmony_ciclass CreatePackage(object): 7140681896Sopenharmony_ci """ 7240681896Sopenharmony_ci Create the update.bin file 7340681896Sopenharmony_ci """ 7440681896Sopenharmony_ci 7540681896Sopenharmony_ci def __init__(self, head_list, component_list, save_path, key_path): 7640681896Sopenharmony_ci self.head_list = head_list 7740681896Sopenharmony_ci self.component_list = component_list 7840681896Sopenharmony_ci self.save_path = save_path 7940681896Sopenharmony_ci self.key_path = key_path 8040681896Sopenharmony_ci self.compinfo_offset = 0 8140681896Sopenharmony_ci self.component_offset = 0 8240681896Sopenharmony_ci self.sign_offset = 0 8340681896Sopenharmony_ci self.hash_info_offset = 0 8440681896Sopenharmony_ci 8540681896Sopenharmony_ci if OPTIONS_MANAGER.not_l2: 8640681896Sopenharmony_ci self.upgrade_compinfo_size = UPGRADE_COMPINFO_SIZE 8740681896Sopenharmony_ci self.header_tlv_type = HEADER_TLV_TYPE 8840681896Sopenharmony_ci else: 8940681896Sopenharmony_ci self.upgrade_compinfo_size = UPGRADE_COMPINFO_SIZE_L2 9040681896Sopenharmony_ci self.header_tlv_type = HEADER_TLV_TYPE_L2 9140681896Sopenharmony_ci 9240681896Sopenharmony_ci def verify_param(self): 9340681896Sopenharmony_ci if self.head_list is None or self.component_list is None or \ 9440681896Sopenharmony_ci self.save_path is None or self.key_path is None: 9540681896Sopenharmony_ci UPDATE_LOGGER.print_log("Check param failed!", UPDATE_LOGGER.ERROR_LOG) 9640681896Sopenharmony_ci return False 9740681896Sopenharmony_ci if os.path.isdir(self.key_path): 9840681896Sopenharmony_ci UPDATE_LOGGER.print_log("Invalid keyname", UPDATE_LOGGER.ERROR_LOG) 9940681896Sopenharmony_ci return False 10040681896Sopenharmony_ci if self.head_list.__sizeof__() <= 0 or self.component_list.__sizeof__() <= 0: 10140681896Sopenharmony_ci UPDATE_LOGGER.print_log("Invalid param", UPDATE_LOGGER.ERROR_LOG) 10240681896Sopenharmony_ci return False 10340681896Sopenharmony_ci return True 10440681896Sopenharmony_ci 10540681896Sopenharmony_ci def write_pkginfo(self, package_file): 10640681896Sopenharmony_ci try: 10740681896Sopenharmony_ci # Type is 1 for package header in TLV format 10840681896Sopenharmony_ci header_tlv = struct.pack(TLV_FMT, self.header_tlv_type, UPGRADE_PKG_HEADER_SIZE) 10940681896Sopenharmony_ci pkg_info_length = \ 11040681896Sopenharmony_ci UPGRADE_RESERVE_LEN + TLV_SIZE + TLV_SIZE + TLV_SIZE + \ 11140681896Sopenharmony_ci UPGRADE_PKG_HEADER_SIZE + UPGRADE_PKG_TIME_SIZE + \ 11240681896Sopenharmony_ci self.upgrade_compinfo_size * self.head_list.entry_count 11340681896Sopenharmony_ci upgrade_pkg_header = struct.pack( 11440681896Sopenharmony_ci UPGRADE_PKG_HEADER_FMT, pkg_info_length, self.head_list.update_file_version, 11540681896Sopenharmony_ci self.head_list.product_update_id, self.head_list.software_version) 11640681896Sopenharmony_ci 11740681896Sopenharmony_ci # Type is 2 for time in TLV format 11840681896Sopenharmony_ci time_tlv = struct.pack(TLV_FMT, 0x02, UPGRADE_PKG_TIME_SIZE) 11940681896Sopenharmony_ci upgrade_pkg_time = struct.pack( 12040681896Sopenharmony_ci UPGRADE_PKG_TIME_FMT, self.head_list.date, self.head_list.time) 12140681896Sopenharmony_ci 12240681896Sopenharmony_ci # Type is 5 for component in TLV format 12340681896Sopenharmony_ci component_tlv = struct.pack( 12440681896Sopenharmony_ci TLV_FMT, 0x05, self.upgrade_compinfo_size * self.head_list.entry_count) 12540681896Sopenharmony_ci except struct.error: 12640681896Sopenharmony_ci UPDATE_LOGGER.print_log("Pack fail!", log_type=UPDATE_LOGGER.ERROR_LOG) 12740681896Sopenharmony_ci return False 12840681896Sopenharmony_ci 12940681896Sopenharmony_ci # write pkginfo 13040681896Sopenharmony_ci pkginfo = header_tlv + upgrade_pkg_header + time_tlv + upgrade_pkg_time + component_tlv 13140681896Sopenharmony_ci try: 13240681896Sopenharmony_ci package_file.write(pkginfo) 13340681896Sopenharmony_ci except IOError: 13440681896Sopenharmony_ci UPDATE_LOGGER.print_log("write fail!", log_type=UPDATE_LOGGER.ERROR_LOG) 13540681896Sopenharmony_ci return False 13640681896Sopenharmony_ci UPDATE_LOGGER.print_log("Write package header complete") 13740681896Sopenharmony_ci return True 13840681896Sopenharmony_ci 13940681896Sopenharmony_ci def write_component_info(self, component, package_file): 14040681896Sopenharmony_ci UPDATE_LOGGER.print_log("component information StartOffset:%s"\ 14140681896Sopenharmony_ci % self.compinfo_offset) 14240681896Sopenharmony_ci if OPTIONS_MANAGER.not_l2: 14340681896Sopenharmony_ci component_addr_size = COMPONENT_ADDR_SIZE 14440681896Sopenharmony_ci else: 14540681896Sopenharmony_ci component_addr_size = COMPONENT_ADDR_SIZE_L2 14640681896Sopenharmony_ci 14740681896Sopenharmony_ci try: 14840681896Sopenharmony_ci package_file.seek(self.compinfo_offset) 14940681896Sopenharmony_ci package_file.write(component.component_addr) 15040681896Sopenharmony_ci self.compinfo_offset += component_addr_size 15140681896Sopenharmony_ci 15240681896Sopenharmony_ci package_file.seek(self.compinfo_offset) 15340681896Sopenharmony_ci component_info = struct.pack( 15440681896Sopenharmony_ci COMPONENT_INFO_FMT, component.id, component.res_type, 15540681896Sopenharmony_ci component.flags, component.type) 15640681896Sopenharmony_ci package_file.write(component_info) 15740681896Sopenharmony_ci self.compinfo_offset += COMPONENT_INFO_FMT_SIZE 15840681896Sopenharmony_ci 15940681896Sopenharmony_ci package_file.seek(self.compinfo_offset) 16040681896Sopenharmony_ci package_file.write(component.version) 16140681896Sopenharmony_ci self.compinfo_offset += COMPONENT_VERSION_SIZE 16240681896Sopenharmony_ci 16340681896Sopenharmony_ci package_file.seek(self.compinfo_offset) 16440681896Sopenharmony_ci component_size = struct.pack( 16540681896Sopenharmony_ci COMPONENT_SIZE_FMT, component.size, component.original_size) 16640681896Sopenharmony_ci package_file.write(component_size) 16740681896Sopenharmony_ci self.compinfo_offset += COMPONENT_SIZE_FMT_SIZE 16840681896Sopenharmony_ci 16940681896Sopenharmony_ci package_file.seek(self.compinfo_offset) 17040681896Sopenharmony_ci package_file.write(component.digest) 17140681896Sopenharmony_ci self.compinfo_offset += COMPONENT_DIGEST_SIZE 17240681896Sopenharmony_ci except (struct.error, IOError): 17340681896Sopenharmony_ci return False 17440681896Sopenharmony_ci return True 17540681896Sopenharmony_ci 17640681896Sopenharmony_ci def write_component(self, component, package_file): 17740681896Sopenharmony_ci UPDATE_LOGGER.print_log("Add component to package StartOffset:%s"\ 17840681896Sopenharmony_ci % self.component_offset) 17940681896Sopenharmony_ci try: 18040681896Sopenharmony_ci with open(component.file_path, "rb") as component_file: 18140681896Sopenharmony_ci component_data = component_file.read() 18240681896Sopenharmony_ci package_file.seek(self.component_offset) 18340681896Sopenharmony_ci package_file.write(component_data) 18440681896Sopenharmony_ci component_len = len(component_data) 18540681896Sopenharmony_ci self.component_offset += component_len 18640681896Sopenharmony_ci except IOError: 18740681896Sopenharmony_ci return False 18840681896Sopenharmony_ci UPDATE_LOGGER.print_log("Write component complete ComponentSize:%s"\ 18940681896Sopenharmony_ci % component_len) 19040681896Sopenharmony_ci return True 19140681896Sopenharmony_ci 19240681896Sopenharmony_ci def calculate_hash(self, package_file): 19340681896Sopenharmony_ci hash_sha256 = hashlib.sha256() 19440681896Sopenharmony_ci remain_len = self.component_offset 19540681896Sopenharmony_ci 19640681896Sopenharmony_ci package_file.seek(0) 19740681896Sopenharmony_ci while remain_len > BLOCK_SIZE: 19840681896Sopenharmony_ci hash_sha256.update(package_file.read(BLOCK_SIZE)) 19940681896Sopenharmony_ci remain_len -= BLOCK_SIZE 20040681896Sopenharmony_ci if remain_len > 0: 20140681896Sopenharmony_ci hash_sha256.update(package_file.read(remain_len)) 20240681896Sopenharmony_ci return hash_sha256.digest() 20340681896Sopenharmony_ci 20440681896Sopenharmony_ci def calculate_header_hash(self, package_file): 20540681896Sopenharmony_ci hash_sha256 = hashlib.sha256() 20640681896Sopenharmony_ci remain_len = self.hash_info_offset 20740681896Sopenharmony_ci 20840681896Sopenharmony_ci package_file.seek(0) 20940681896Sopenharmony_ci while remain_len > BLOCK_SIZE: 21040681896Sopenharmony_ci hash_sha256.update(package_file.read(BLOCK_SIZE)) 21140681896Sopenharmony_ci remain_len -= BLOCK_SIZE 21240681896Sopenharmony_ci if remain_len > 0: 21340681896Sopenharmony_ci hash_sha256.update(package_file.read(remain_len)) 21440681896Sopenharmony_ci return hash_sha256.digest() 21540681896Sopenharmony_ci 21640681896Sopenharmony_ci def sign_digest_with_pss(self, digest): 21740681896Sopenharmony_ci try: 21840681896Sopenharmony_ci with open(self.key_path, 'rb') as f_r: 21940681896Sopenharmony_ci key_data = f_r.read() 22040681896Sopenharmony_ci private_key = serialization.load_pem_private_key( 22140681896Sopenharmony_ci key_data, 22240681896Sopenharmony_ci password=None, 22340681896Sopenharmony_ci backend=default_backend()) 22440681896Sopenharmony_ci 22540681896Sopenharmony_ci pad = padding.PSS( 22640681896Sopenharmony_ci mgf=padding.MGF1(hashes.SHA256()), 22740681896Sopenharmony_ci salt_length=padding.PSS.MAX_LENGTH) 22840681896Sopenharmony_ci 22940681896Sopenharmony_ci signature = private_key.sign(digest, pad, hashes.SHA256()) 23040681896Sopenharmony_ci except (OSError, ValueError): 23140681896Sopenharmony_ci return False 23240681896Sopenharmony_ci return signature 23340681896Sopenharmony_ci 23440681896Sopenharmony_ci def sign_digest(self, digest): 23540681896Sopenharmony_ci try: 23640681896Sopenharmony_ci with open(self.key_path, 'rb') as f_r: 23740681896Sopenharmony_ci key_data = f_r.read() 23840681896Sopenharmony_ci private_key = serialization.load_pem_private_key( 23940681896Sopenharmony_ci key_data, 24040681896Sopenharmony_ci password=None, 24140681896Sopenharmony_ci backend=default_backend()) 24240681896Sopenharmony_ci signature = private_key.sign(digest, padding.PKCS1v15(), hashes.SHA256()) 24340681896Sopenharmony_ci except (OSError, ValueError): 24440681896Sopenharmony_ci return False 24540681896Sopenharmony_ci return signature 24640681896Sopenharmony_ci 24740681896Sopenharmony_ci def sign(self, sign_algo): 24840681896Sopenharmony_ci with open(self.save_path, "rb+") as package_file: 24940681896Sopenharmony_ci # calculate hash for .bin package 25040681896Sopenharmony_ci digest = self.calculate_hash(package_file) 25140681896Sopenharmony_ci if not digest: 25240681896Sopenharmony_ci UPDATE_LOGGER.print_log("calculate hash for .bin package failed", 25340681896Sopenharmony_ci log_type=UPDATE_LOGGER.ERROR_LOG) 25440681896Sopenharmony_ci return False 25540681896Sopenharmony_ci 25640681896Sopenharmony_ci # sign .bin package 25740681896Sopenharmony_ci if sign_algo == SIGN_ALGO_RSA: 25840681896Sopenharmony_ci signature = self.sign_digest(digest) 25940681896Sopenharmony_ci elif sign_algo == SIGN_ALGO_PSS: 26040681896Sopenharmony_ci signature = self.sign_digest_with_pss(digest) 26140681896Sopenharmony_ci else: 26240681896Sopenharmony_ci UPDATE_LOGGER.print_log("invalid sign_algo!", log_type=UPDATE_LOGGER.ERROR_LOG) 26340681896Sopenharmony_ci return False 26440681896Sopenharmony_ci if not signature: 26540681896Sopenharmony_ci UPDATE_LOGGER.print_log("sign .bin package failed!", log_type=UPDATE_LOGGER.ERROR_LOG) 26640681896Sopenharmony_ci return False 26740681896Sopenharmony_ci 26840681896Sopenharmony_ci if len(signature) == SIGN_SHA384_LEN: 26940681896Sopenharmony_ci self.sign_offset += SIGN_SHA256_LEN 27040681896Sopenharmony_ci 27140681896Sopenharmony_ci # write signed .bin package 27240681896Sopenharmony_ci package_file.seek(self.sign_offset) 27340681896Sopenharmony_ci package_file.write(signature) 27440681896Sopenharmony_ci UPDATE_LOGGER.print_log( 27540681896Sopenharmony_ci ".bin package signing success! SignOffset: %s" % self.sign_offset) 27640681896Sopenharmony_ci return True 27740681896Sopenharmony_ci 27840681896Sopenharmony_ci def sign_header(self, sign_algo, hash_check_data, package_file): 27940681896Sopenharmony_ci # calculate hash for .bin package 28040681896Sopenharmony_ci digest = self.calculate_header_hash(package_file) 28140681896Sopenharmony_ci if not digest: 28240681896Sopenharmony_ci UPDATE_LOGGER.print_log("calculate hash for .bin package failed", 28340681896Sopenharmony_ci log_type=UPDATE_LOGGER.ERROR_LOG) 28440681896Sopenharmony_ci return False 28540681896Sopenharmony_ci 28640681896Sopenharmony_ci # sign .bin header 28740681896Sopenharmony_ci if sign_algo == SIGN_ALGO_RSA: 28840681896Sopenharmony_ci signature = self.sign_digest(digest) 28940681896Sopenharmony_ci elif sign_algo == SIGN_ALGO_PSS: 29040681896Sopenharmony_ci signature = self.sign_digest_with_pss(digest) 29140681896Sopenharmony_ci else: 29240681896Sopenharmony_ci UPDATE_LOGGER.print_log("invalid sign_algo!", log_type=UPDATE_LOGGER.ERROR_LOG) 29340681896Sopenharmony_ci return False 29440681896Sopenharmony_ci if not signature: 29540681896Sopenharmony_ci UPDATE_LOGGER.print_log("sign .bin package failed!", log_type=UPDATE_LOGGER.ERROR_LOG) 29640681896Sopenharmony_ci return False 29740681896Sopenharmony_ci 29840681896Sopenharmony_ci # write signed .bin header 29940681896Sopenharmony_ci hash_check_data.write_signdata(signature) 30040681896Sopenharmony_ci package_file.seek(self.hash_info_offset) 30140681896Sopenharmony_ci package_file.write(hash_check_data.signdata) 30240681896Sopenharmony_ci self.hash_info_offset += len(hash_check_data.signdata) 30340681896Sopenharmony_ci UPDATE_LOGGER.print_log( 30440681896Sopenharmony_ci ".bin package header signing success! SignOffset: %s" % self.hash_info_offset) 30540681896Sopenharmony_ci return True 30640681896Sopenharmony_ci 30740681896Sopenharmony_ci def create_package(self): 30840681896Sopenharmony_ci """ 30940681896Sopenharmony_ci Create the update.bin file 31040681896Sopenharmony_ci return: update package creation result 31140681896Sopenharmony_ci """ 31240681896Sopenharmony_ci if not self.verify_param(): 31340681896Sopenharmony_ci UPDATE_LOGGER.print_log("verify param failed!", UPDATE_LOGGER.ERROR_LOG) 31440681896Sopenharmony_ci return False 31540681896Sopenharmony_ci 31640681896Sopenharmony_ci hash_check_data = CreateHash(HashType.SHA256, self.head_list.entry_count) 31740681896Sopenharmony_ci hash_check_data.write_hashinfo() 31840681896Sopenharmony_ci package_fd = os.open(self.save_path, os.O_RDWR | os.O_CREAT, 0o755) 31940681896Sopenharmony_ci with os.fdopen(package_fd, "wb+") as package_file: 32040681896Sopenharmony_ci # Add information to package 32140681896Sopenharmony_ci if not self.write_pkginfo(package_file): 32240681896Sopenharmony_ci UPDATE_LOGGER.print_log("Write pkginfo failed!", log_type=UPDATE_LOGGER.ERROR_LOG) 32340681896Sopenharmony_ci return False 32440681896Sopenharmony_ci # Add component to package 32540681896Sopenharmony_ci self.compinfo_offset = UPGRADE_FILE_HEADER_LEN 32640681896Sopenharmony_ci self.component_offset = UPGRADE_FILE_HEADER_LEN + \ 32740681896Sopenharmony_ci self.head_list.entry_count * self.upgrade_compinfo_size + \ 32840681896Sopenharmony_ci UPGRADE_RESERVE_LEN + SIGN_SHA256_LEN + SIGN_SHA384_LEN 32940681896Sopenharmony_ci for i in range(0, self.head_list.entry_count): 33040681896Sopenharmony_ci UPDATE_LOGGER.print_log("Add component %s" % self.component_list[i].component_addr) 33140681896Sopenharmony_ci if not self.write_component_info(self.component_list[i], package_file): 33240681896Sopenharmony_ci UPDATE_LOGGER.print_log("write component info failed: %s" 33340681896Sopenharmony_ci % self.component_list[i].component_addr, UPDATE_LOGGER.ERROR_LOG) 33440681896Sopenharmony_ci return False 33540681896Sopenharmony_ci if OPTIONS_MANAGER.sd_card and (not hash_check_data.write_component_hash_data(self.component_list[i])): 33640681896Sopenharmony_ci UPDATE_LOGGER.print_log("write component hash data failed: %s" 33740681896Sopenharmony_ci % self.component_list[i].component_addr, UPDATE_LOGGER.ERROR_LOG) 33840681896Sopenharmony_ci return False 33940681896Sopenharmony_ci 34040681896Sopenharmony_ci try: 34140681896Sopenharmony_ci # Add descriptPackageId to package 34240681896Sopenharmony_ci package_file.seek(self.compinfo_offset) 34340681896Sopenharmony_ci package_file.write( 34440681896Sopenharmony_ci (self.head_list.describe_package_id.decode().ljust(UPGRADE_RESERVE_LEN, "\0")).encode()) 34540681896Sopenharmony_ci except IOError: 34640681896Sopenharmony_ci UPDATE_LOGGER.print_log("Add descriptPackageId failed!", log_type=UPDATE_LOGGER.ERROR_LOG) 34740681896Sopenharmony_ci return False 34840681896Sopenharmony_ci self.hash_info_offset = self.compinfo_offset + UPGRADE_RESERVE_LEN 34940681896Sopenharmony_ci if OPTIONS_MANAGER.sd_card: 35040681896Sopenharmony_ci try: 35140681896Sopenharmony_ci # Add hash check data to package 35240681896Sopenharmony_ci hash_check_data.write_hashdata() 35340681896Sopenharmony_ci package_file.seek(self.hash_info_offset) 35440681896Sopenharmony_ci package_file.write(hash_check_data.hashinfo_value + hash_check_data.hashdata) 35540681896Sopenharmony_ci self.hash_info_offset += len(hash_check_data.hashinfo_value + hash_check_data.hashdata) 35640681896Sopenharmony_ci 35740681896Sopenharmony_ci except IOError: 35840681896Sopenharmony_ci UPDATE_LOGGER.print_log("Add hash check data failed!", log_type=UPDATE_LOGGER.ERROR_LOG) 35940681896Sopenharmony_ci return False 36040681896Sopenharmony_ci self.sign_header(SIGN_ALGO_RSA, hash_check_data, package_file) 36140681896Sopenharmony_ci self.component_offset = self.hash_info_offset 36240681896Sopenharmony_ci for i in range(0, self.head_list.entry_count): 36340681896Sopenharmony_ci if not self.write_component(self.component_list[i], package_file): 36440681896Sopenharmony_ci UPDATE_LOGGER.print_log("write component failed: %s" 36540681896Sopenharmony_ci % self.component_list[i].component_addr, UPDATE_LOGGER.ERROR_LOG) 36640681896Sopenharmony_ci return False 36740681896Sopenharmony_ci UPDATE_LOGGER.print_log("Write update package complete") 36840681896Sopenharmony_ci return True