1#!/usr/bin/env python3 2# coding=utf-8 3 4''' 5* Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 6* Licensed under the Apache License, Version 2.0 (the "License"); 7* you may not use this file except in compliance with the License. 8* You may obtain a copy of the License at 9* 10* http://www.apache.org/licenses/LICENSE-2.0 11* 12* Unless required by applicable law or agreed to in writing, software 13* distributed under the License is distributed on an "AS IS" BASIS, 14* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15* See the License for the specific language governing permissions and 16* limitations under the License. 17* 18* Description: part of hupg build scripts 19''' 20 21import os 22import re 23import hashlib 24import sys 25import subprocess 26import struct 27from ctypes import * 28from Crypto.Hash import SHA 29from Crypto.Hash import SHA256 30from Crypto.PublicKey import RSA 31from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5 32from Crypto.Signature import PKCS1_PSS as Signature_pss 33from ecdsa import SigningKey 34from ecdsa import VerifyingKey 35import make_upg_user_info as USER_INFO 36 37###############################定义基本类型############################################### 38hi_char=c_char 39hi_s8=c_byte 40hi_u8=c_ubyte 41hi_s16=c_short 42hi_u16=c_ushort 43hi_s32=c_int 44hi_u32=c_uint 45 46class sign_alg_param(Structure): 47 _fields_ = [ 48 ("hash_alg", hi_u32, 16), 49 ("sign_alg", hi_u32, 6), 50 ("sign_param", hi_u32, 10), 51 ] 52 53class upg_rsa_key(Structure): 54 _fields_ = [ 55 ("mod_n", hi_u8*256), 56 ("exp_e", hi_u8*4), 57 ("padding", hi_u8*28), 58 ] 59 60class upg_rsa_sign(Structure): 61 _fields_ = [ 62 ("sign", hi_u8*256), 63 ] 64 65class upg_ecc_key(Structure): 66 _fields_ = [ 67 ("px", hi_u8*32), 68 ("py", hi_u8*32), 69 ("padding", hi_u8*224), 70 ] 71 72class upg_ecc_sign(Structure): 73 _fields_ = [ 74 ("r", hi_u8*32), 75 ("s", hi_u8*32), 76 ("padding", hi_u8*192), 77 ] 78 79class upg_sha256_key(Structure): 80 _fields_ = [ 81 ("padding", hi_u8*288), 82 ] 83 84class upg_sha256_sign(Structure): 85 _fields_ = [ 86 ("check_sum", hi_u8*32), 87 ("padding", hi_u8*224), 88 ] 89 90class hi_upg_user_info(Structure): 91 _fields_ = [ 92 ("reserved", hi_u8*32), 93 ] 94 95class hi_upg_common_head(Structure): 96 _fields_ = [ 97 ("image_id", hi_u32), 98 ("struct_version", hi_u32), 99 ("section_offset", hi_u32), 100 ("section_len", hi_u32), 101 ("user_info", hi_upg_user_info), 102 ("file_type", hi_u8), 103 ("file_version", hi_u8), 104 ("encrypt_flag", hi_u8), 105 ("file_attr", hi_u8), 106 ("file_len", hi_u32), 107 ("key_len", hi_u32), 108 ("param", sign_alg_param), 109 ("aes_key", hi_u8*16), 110 ("aes_iv", hi_u8*16), 111 ] 112 113class hi_upg_section_head(Structure): 114 _fields_ = [ 115 ("image_id", hi_u32), 116 ("struct_version", hi_u32), 117 ("param", sign_alg_param), 118 ("section_count", hi_u8), 119 ("reserved", hi_u8*27), 120 ("section0_compress", hi_u8), 121 ("pad0", hi_u8*3), 122 ("section0_offset", hi_u32), 123 ("section0_len", hi_u32), 124 ("section1_compress", hi_u8), 125 ("pad1", hi_u8*3), 126 ("section1_offset", hi_u32), 127 ("section1_len", hi_u32), 128 ] 129 130def lzma_compress_bin(src_file, dst_file, lzma_tool): 131 print('lzma compress tool :', lzma_tool) 132 print('lzma src file :', src_file) 133 print('lzma out file :', dst_file) 134 cmd_list = [] 135 cmd_list.append(lzma_tool) 136 cmd_list.append('-d16 -lc2 -lp2 e') 137 cmd_list.append(src_file) 138 cmd_list.append(dst_file) 139 str_cmd=' '.join(cmd_list) 140 subprocess.run(str_cmd, shell=True) 141 142def aes_encrypt_bin(src_file, dst_file, offset, size, aes_key_file, aes_encrypt_tool): 143 print('aes encrypt src file:', src_file) 144 print('aes encrypt out file:', dst_file) 145 print('aes key file :', aes_key_file) 146 print('aes encrypt tool :', aes_encrypt_tool) 147 cmd_list = [] 148 cmd_list.append(aes_encrypt_tool) 149 cmd_list.append('-i') 150 cmd_list.append(src_file) 151 cmd_list.append('-o') 152 cmd_list.append(dst_file) 153 cmd_list.append('-u') 154 cmd_list.append(aes_key_file) 155 cmd_list.append('-f %x'%(offset)) 156 cmd_list.append('-z %x'%(size)) 157 str_cmd=' '.join(cmd_list) 158 print("[aes-str-cmd]", str_cmd) 159 subprocess.run(str_cmd, shell=True) 160 161def print_upg_info(image_file, upg_bin): 162 st_hupg = hi_upg_common_head.from_buffer(upg_bin) 163 164 print("-------------%s image info print start-------------"%(image_file)) 165 print("[image_id=0x%x][struct_version=0x%x]]"%(st_hupg.image_id, st_hupg.struct_version)) 166 print("[section_offset=0x%x][section_len=0x%x]"%(st_hupg.section_offset, st_hupg.section_len)) 167 print("[file_type=0x%x][file_version=0x%x][encrypt_flag=0x%x]"%( 168 st_hupg.file_type, st_hupg.file_version, st_hupg.encrypt_flag)) 169 print("[file_len=0x%x][key_len=0x%x]"%(st_hupg.file_len, st_hupg.key_len)) 170 print("[file_attr=0x%x]"%(st_hupg.file_attr)) 171 print("[hash_alg=0x%x][sign_alg=0x%x][sign_param=0x%x]"%( 172 st_hupg.param.hash_alg, st_hupg.param.sign_alg, st_hupg.param.sign_param)) 173 print("[aes_key[0-1-14-15]=[0x%x][0x%x][0x%x][0x%x]]"%( 174 st_hupg.aes_key[0], st_hupg.aes_key[1], st_hupg.aes_key[14], st_hupg.aes_key[15])) 175 print("[aes_iv [0-1-14-15]=[0x%x][0x%x][0x%x][0x%x]]"%( 176 st_hupg.aes_iv[0], st_hupg.aes_iv[1], st_hupg.aes_iv[14], st_hupg.aes_iv[15])) 177 178 #打印common段key信息、common段签名信息、section段签名信息 179 if st_hupg.param.sign_alg < 0x10: 180 common_key_offset = sizeof(hi_upg_common_head) 181 common_sign_offset = sizeof(hi_upg_common_head) + st_hupg.key_len 182 section_sign_offset = st_hupg.section_offset + sizeof(hi_upg_section_head) 183 print('[common key][000]=[0x%x]'%(upg_bin[common_key_offset])) 184 print('[common key][001]=[0x%x]'%(upg_bin[common_key_offset + 1])) 185 print('[common key][254]=[0x%x]'%(upg_bin[common_key_offset + 254])) 186 print('[common key][255]=[0x%x]'%(upg_bin[common_key_offset + 255])) 187 print('[common sign][000]=[0x%x]'%(upg_bin[common_sign_offset])) 188 print('[common sign][001]=[0x%x]'%(upg_bin[common_sign_offset + 1])) 189 print('[common sign][254]=[0x%x]'%(upg_bin[common_sign_offset + 254])) 190 print('[common sign][255]=[0x%x]'%(upg_bin[common_sign_offset + 255])) 191 print('[section sign][000]=[0x%x]'%(upg_bin[section_sign_offset])) 192 print('[section sign][001]=[0x%x]'%(upg_bin[section_sign_offset + 1])) 193 print('[section sign][254]=[0x%x]'%(upg_bin[section_sign_offset + 254])) 194 print('[section sign][255]=[0x%x]'%(upg_bin[section_sign_offset + 255])) 195 elif st_hupg.param.sign_alg == 0x10: 196 common_key_offset = sizeof(hi_upg_common_head) 197 common_sign_offset = sizeof(hi_upg_common_head) + st_hupg.key_len 198 section_sign_offset = st_hupg.section_offset + sizeof(hi_upg_section_head) 199 print('[common key][00]=[0x%x]'%(upg_bin[common_key_offset])) 200 print('[common key][01]=[0x%x]'%(upg_bin[common_key_offset + 1])) 201 print('[common key][62]=[0x%x]'%(upg_bin[common_key_offset + 62])) 202 print('[common key][63]=[0x%x]'%(upg_bin[common_key_offset + 63])) 203 print('[common sign][00]=[0x%x]'%(upg_bin[common_sign_offset])) 204 print('[common sign][01]=[0x%x]'%(upg_bin[common_sign_offset + 1])) 205 print('[common sign][62]=[0x%x]'%(upg_bin[common_sign_offset + 62])) 206 print('[common sign][63]=[0x%x]'%(upg_bin[common_sign_offset + 63])) 207 print('[section sign][00]=[0x%x]'%(upg_bin[section_sign_offset])) 208 print('[section sign][01]=[0x%x]'%(upg_bin[section_sign_offset + 1])) 209 print('[section sign][62]=[0x%x]'%(upg_bin[section_sign_offset + 62])) 210 print('[section sign][63]=[0x%x]'%(upg_bin[section_sign_offset + 63])) 211 else: 212 common_key_offset = sizeof(hi_upg_common_head) 213 common_sign_offset = sizeof(hi_upg_common_head) + st_hupg.key_len 214 section_sign_offset = st_hupg.section_offset + sizeof(hi_upg_section_head) 215 print('[common key][00]=[0x%x]'%(upg_bin[common_key_offset])) 216 print('[common key][01]=[0x%x]'%(upg_bin[common_key_offset+1])) 217 print('[common key][30]=[0x%x]'%(upg_bin[common_key_offset+30])) 218 print('[common key][31]=[0x%x]'%(upg_bin[common_key_offset+31])) 219 print('[common sign][00]=[0x%x]'%(upg_bin[common_sign_offset])) 220 print('[common sign][01]=[0x%x]'%(upg_bin[common_sign_offset+1])) 221 print('[common sign][30]=[0x%x]'%(upg_bin[common_sign_offset+30])) 222 print('[common sign][31]=[0x%x]'%(upg_bin[common_sign_offset+31])) 223 print('[section sign][00]=[0x%x]'%(upg_bin[section_sign_offset])) 224 print('[section sign][01]=[0x%x]'%(upg_bin[section_sign_offset+1])) 225 print('[section sign][30]=[0x%x]'%(upg_bin[section_sign_offset+30])) 226 print('[section sign][31]=[0x%x]'%(upg_bin[section_sign_offset+31])) 227 228 #打印section段固定头信息 229 section_head = hi_upg_section_head.from_buffer( 230 upg_bin[st_hupg.section_offset:st_hupg.section_offset + sizeof(hi_upg_section_head)]) 231 print("[image_id=0x%x][struct_version=0x%x]]"%( 232 section_head.image_id, section_head.struct_version)) 233 print("[hash_alg=0x%x][sign_alg=0x%x][sign_param=0x%x]"%( 234 section_head.param.hash_alg, section_head.param.sign_alg, section_head.param.sign_param)) 235 print("[section_count=0x%x]"%(section_head.section_count)) 236 print("[section0_compress=0x%x][section0_offset=0x%x][section0_len=0x%x]"%(section_head.section0_compress, section_head.section0_offset, section_head.section0_len)) 237 print("[section1_compress=0x%x][section1_offset=0x%x][section1_len=0x%x]"%(section_head.section1_compress, section_head.section1_offset, section_head.section1_len)) 238 print("-------------%s image info print end--------------"%(image_file)) 239 240def print_hbin_info(image_file, upg_bin, bin_size): 241 st_hupg = hi_upg_common_head.from_buffer(upg_bin) 242 print("-------------%s image info print start-------------"%(image_file)) 243 print("[bin_size]=[0x%x]"%(bin_size)) 244 print("[image_id=0x%x][struct_version=0x%x]]"%(st_hupg.image_id, st_hupg.struct_version)) 245 print("[section_offset=0x%x][section_len=0x%x]"%(st_hupg.section_offset, st_hupg.section_len)) 246 print("[file_type=0x%x][file_version=0x%x][encrypt_flag=0x%x]"%( 247 st_hupg.file_type, st_hupg.file_version, st_hupg.encrypt_flag)) 248 print("[file_len=0x%x][key_len=0x%x]"%(st_hupg.file_len, st_hupg.key_len)) 249 print("[hash_alg=0x%x][sign_alg=0x%x][sign_param=0x%x]"%( 250 st_hupg.param.hash_alg, st_hupg.param.sign_alg, st_hupg.param.sign_param)) 251 print("[aes_key[0,1,14,15]=[0x%x][0x%x][0x%x][0x%x]]"%( 252 st_hupg.aes_key[0], st_hupg.aes_key[1], st_hupg.aes_key[14], st_hupg.aes_key[15])) 253 print("[aes_iv[0,1,14,15]=[0x%x][0x%x][0x%x][0x%x]]"%( 254 st_hupg.aes_iv[0], st_hupg.aes_iv[1], st_hupg.aes_iv[14], st_hupg.aes_iv[15])) 255 print("-------------%s image info print end--------------"%(image_file)) 256 257def int_2_bin_list(val, array_size): 258 L = bytearray(array_size) 259 i = array_size - 1 260 261 while i != 0: 262 L[i] = val%256 263 val = val//256 264 i = i - 1 265 L[0] = val 266 return (L) 267 268def convert_int(value): 269 match1 = re.match(r'\s*0x', value) 270 match2 = re.match(r'\s*0X', value) 271 if match1 or match2: 272 return int(value, 16) 273 else: 274 return int(value, 10) 275 276def make_secure_key(alg_dir_path, sign_alg): 277 if sign_alg < 0x10: 278 key_bin = bytearray(sizeof(upg_rsa_key)) 279 rsa_key = upg_rsa_key.from_buffer(key_bin) 280 second_key_dir = os.path.join(alg_dir_path, r'upg_private_rsa_2.pem') 281 with open(second_key_dir, 'rb') as f: 282 temp_bin = f.read() 283 second_key = RSA.importKey(temp_bin) 284 key_n_2 = int_2_bin_list(second_key.n, sizeof(rsa_key.mod_n)) 285 key_bin[0:sizeof(rsa_key.mod_n)] = key_n_2 286 key_bin[sizeof(rsa_key.mod_n):sizeof(rsa_key.mod_n) + sizeof(rsa_key.exp_e)] = int_2_bin_list(65537, sizeof(rsa_key.exp_e)) #exp_e 287 elif sign_alg == 0x10: 288 key_bin = bytearray(sizeof(upg_ecc_key)) 289 ecc_key = upg_ecc_key.from_buffer(key_bin) 290 second_key_dir = os.path.join(alg_dir_path, r'upg_private_ecc_2.pem') 291 with open(second_key_dir) as f: 292 sk = SigningKey.from_pem(f.read()) 293 vk = sk.verifying_key 294 second_key = vk.to_string().hex() 295 key = bytearray.fromhex(second_key) 296 key_bin[0:(sizeof(ecc_key.px) + sizeof(ecc_key.py))] = key 297 else: 298 key_bin = bytearray(sizeof(upg_sha256_key)) 299 return key_bin 300 301def make_rsa_pss_signature(alg_dir_path, common_head_content, section_content): 302 first_key_dir = os.path.join(alg_dir_path, r'upg_private_rsa_1.pem') 303 second_key_dir = os.path.join(alg_dir_path, r'upg_private_rsa_2.pem') 304 with open(first_key_dir, 'rb') as f: 305 temp_bin = f.read() 306 first_key = RSA.importKey(temp_bin) 307 308 with open(second_key_dir, 'rb') as f: 309 temp_bin = f.read() 310 second_key = RSA.importKey(temp_bin) 311 312 signer = Signature_pss.new(first_key) 313 digest = SHA256.new() 314 digest.update(bytes(common_head_content)) 315 signature_1 = signer.sign(digest) 316 317 signer = Signature_pss.new(second_key) 318 digest = SHA256.new() 319 digest.update(bytes(section_content)) 320 signature_2 = signer.sign(digest) 321 322 return (signature_1, signature_2) 323 324def make_rsa_pkcs_signature(alg_dir_path, common_head_content, section_content): 325 first_key_dir = os.path.join(alg_dir_path, r'upg_private_rsa_1.pem') 326 second_key_dir = os.path.join(alg_dir_path, r'upg_private_rsa_2.pem') 327 with open(first_key_dir, 'rb') as f: 328 temp_bin = f.read() 329 first_key = RSA.importKey(temp_bin) 330 331 with open(second_key_dir, 'rb') as f: 332 temp_bin = f.read() 333 second_key = RSA.importKey(temp_bin) 334 335 signer = Signature_pkcs1_v1_5.new(first_key) 336 digest = SHA256.new() 337 digest.update(bytes(common_head_content)) 338 signature_1 = signer.sign(digest) 339 340 signer = Signature_pkcs1_v1_5.new(second_key) 341 digest = SHA256.new() 342 digest.update(bytes(section_content)) 343 signature_2 = signer.sign(digest) 344 345 return (signature_1, signature_2) 346 347def make_ecc_secure_signature(alg_dir_path, common_head_content, section_content): 348 first_key_dir = os.path.join(alg_dir_path, r'upg_private_ecc_1.pem') 349 second_key_dir = os.path.join(alg_dir_path, r'upg_private_ecc_2.pem') 350 with open(first_key_dir, 'rb') as f: 351 first_key = SigningKey.from_pem(f.read()) 352 353 with open(second_key_dir, 'rb') as f: 354 second_key = SigningKey.from_pem(f.read()) 355 356 signature_1 = first_key.sign(common_head_content, hashfunc=hashlib.sha256) 357 signature_2 = second_key.sign(section_content, hashfunc=hashlib.sha256) 358 359 signature_1_bin = bytearray(sizeof(upg_ecc_sign)) 360 signature = upg_ecc_sign.from_buffer(signature_1_bin) 361 signature_1_bin[0:sizeof(signature.r) + sizeof(signature.s)] = signature_1 362 signature_2_bin = bytearray(sizeof(upg_ecc_sign)) 363 signature = upg_ecc_sign.from_buffer(signature_2_bin) 364 signature_2_bin[0:sizeof(signature.r) + sizeof(signature.s)] = signature_2 365 366 return (signature_1_bin, signature_2_bin) 367 368def make_sha256_unsecure_signature(common_head_content, section_content): 369 #common段非安全签名 370 signature_1_bin = bytearray(sizeof(upg_sha256_sign)) 371 signature = upg_sha256_sign.from_buffer(signature_1_bin) 372 common_head_sh = hashlib.sha256() 373 common_head_sh.update(common_head_content) 374 common_head_hash = common_head_sh.digest() 375 signature_1_bin[0:sizeof(signature.check_sum)] = common_head_hash 376 377 #section段非安全签名 378 signature_2_bin = bytearray(sizeof(upg_sha256_sign)) 379 signature = upg_sha256_sign.from_buffer(signature_2_bin) 380 section_head_sh = hashlib.sha256() 381 section_head_sh.update(section_content) 382 section_head_hash = section_head_sh.digest() 383 signature_2_bin[0:sizeof(signature.check_sum)] = section_head_hash 384 return (signature_1_bin, signature_2_bin) 385 386def make_part_offset_size(temp_offset, bin_size): 387 if bin_size != 0: 388 section_offset = temp_offset[0] 389 section_size = bin_size 390 else: 391 section_offset = 0 392 section_size = 0 393 394 temp_offset[0] = temp_offset[0] + section_size 395 return (section_offset, section_size) 396 397def make_upg_get_aes_key(alg_dir_path): 398 aes_key_bin = bytearray(16) 399 aes_key_file = os.path.join(alg_dir_path, r'upg_aes_key.txt') 400 with open(aes_key_file) as f: 401 lines = f.readlines() 402 aes_key_bin = bytearray.fromhex(lines[1].split(':')[1].split(';')[0].strip()) 403 return aes_key_bin 404 405def make_upg_get_aes_iv(alg_dir_path): 406 aes_iv_bin = bytearray(16) 407 aes_key_file = os.path.join(alg_dir_path, r'upg_aes_key.txt') 408 with open(aes_key_file) as f: 409 lines = f.readlines() 410 aes_iv_bin = bytearray.fromhex(lines[2].split(':')[1].split(';')[0].strip()) 411 return aes_iv_bin 412 413def make_upg_only(image_id, file_ver, encrypt_flag, file_type, section_bin_list, section_compress_list, alg_dir_path, max_size, sign_alg, chip_name, file_attr): 414 section_count = len(section_bin_list) 415 section_offset_list = [] 416 section_size_list = [] 417 temp_offset = [0] 418 419 #common固定头大小偏移 420 (common_head_offset, common_head_size) = make_part_offset_size(temp_offset, sizeof(hi_upg_common_head)) 421 print('[common_head_offset=%d][common_head_size=%d]'%(common_head_offset, common_head_size)) 422 423 #common密钥区大小偏移、固定头签名大小偏移(不同签名算法统一按最大值处理(密钥288Byte/签名256Byte),填实际长度字节,多余的部分填0) 424 if sign_alg < 0x10: 425 #RSA2048 426 (common_key_offset, common_key_size) = make_part_offset_size(temp_offset, sizeof(upg_rsa_key)) 427 (common_head_sign_offset, common_head_sign_size) = make_part_offset_size(temp_offset, sizeof(upg_rsa_sign)) 428 elif sign_alg == 0x10: 429 #ECDSA256 430 (common_key_offset, common_key_size) = make_part_offset_size(temp_offset, sizeof(upg_ecc_key)) 431 (common_head_sign_offset, common_head_sign_size) = make_part_offset_size(temp_offset, sizeof(upg_ecc_sign)) 432 else: 433 #SHA256 434 (common_key_offset, common_key_size) = make_part_offset_size(temp_offset, sizeof(upg_sha256_key)) 435 (common_head_sign_offset, common_head_sign_size) = make_part_offset_size(temp_offset, sizeof(upg_sha256_sign)) 436 437 print('[common_key_offset=%d][common_key_size=%d]'%(common_key_offset, common_key_size)) 438 print('[common_head_sign_offset=%d][common_head_sign_size=%d]'%(common_head_sign_offset, common_head_sign_size)) 439 440 #section固定头大小偏移 441 (section_head_offset, section_head_size) = make_part_offset_size(temp_offset, sizeof(hi_upg_section_head)) 442 print('[section_head_offset=%d][section_head_size=%d]'%(section_head_offset, section_head_size)) 443 #section签名大小偏移、秘钥信息。签名算法不同,填充大小不同 444 if sign_alg < 0x10: 445 (upg_file_sign_offset, upg_file_sign_size) = make_part_offset_size(temp_offset, sizeof(upg_rsa_sign)) 446 elif sign_alg == 0x10: 447 (upg_file_sign_offset, upg_file_sign_size) = make_part_offset_size(temp_offset, sizeof(upg_ecc_sign)) 448 else: 449 (upg_file_sign_offset, upg_file_sign_size) = make_part_offset_size(temp_offset, sizeof(upg_sha256_sign)) 450 print('[upg_file_sign_offset=%d][upg_file_sign_size=%d]'%(upg_file_sign_offset, upg_file_sign_size)) 451 452 #section各个镜像大小和偏移 453 i = 0 454 while i < section_count: 455 (offset, size) = make_part_offset_size(temp_offset, len(section_bin_list[i])) 456 section_offset_list.append(offset) 457 section_size_list.append(size) 458 i = i + 1 459 460 #section填充域大小和偏移:AES加密要求16字节对齐 461 temp_size_1 = temp_offset[0] 462 temp_size_2 = temp_size_1//16 463 temp_size_2 = temp_size_2*16 464 padding_size = temp_size_1 - temp_size_2 465 if temp_size_1 == temp_size_2: 466 padding_size = 0 467 else: 468 padding_size = temp_size_2 + 16 - temp_size_1 469 470 (padding_offset, padding_size) = make_part_offset_size(temp_offset, padding_size)#hupg+nv部分大小 471 print('[padding_offset=%d][padding_size=%d]'%(padding_offset, padding_size)) 472 473 #初始化upg_bin 474 upg_bin = bytearray(temp_offset[0]) 475 476 #升级文件大小上限从分区获取 477 if len(upg_bin) > max_size: 478 sys.exit("\033[91m[ERR]upg size>%dKB FROM:%s\033[0m"%(max_size/1024, os.path.realpath(__file__))) 479 480 #填充common段固定头 481 common_head_bin = upg_bin[common_head_offset:common_head_offset + common_head_size] 482 common_head = hi_upg_common_head.from_buffer(common_head_bin) 483 common_head.image_id = image_id 484 common_head.struct_version = 0 485 common_head.section_offset = section_head_offset 486 common_head.section_len = len(upg_bin) - section_head_offset 487 common_head.file_type = file_type 488 common_head.file_version = file_ver 489 common_head.encrypt_flag = encrypt_flag 490 common_head.file_attr = file_attr 491 common_head.file_len = len(upg_bin) 492 common_head.key_len = common_key_size 493 common_head.param.hash_alg = 0 494 common_head.param.sign_alg = sign_alg 495 common_head.param.sign_param = 0 496 #image_id struct_version section_offset section_offset 497 user_info_offset = sizeof(c_int) + sizeof(c_int) + sizeof(c_int) + sizeof(c_int) 498 common_head_bin[user_info_offset : (user_info_offset + sizeof(hi_upg_user_info))] = USER_INFO.fill_user_info(chip_name) 499 if encrypt_flag != 0x42: 500 common_head_bin[(common_head_size - 32) : (common_head_size - 16)] = make_upg_get_aes_key(alg_dir_path) 501 common_head_bin[(common_head_size - 16) : common_head_size] = make_upg_get_aes_iv(alg_dir_path) 502 upg_bin[common_head_offset:common_head_offset + common_head_size] = common_head_bin 503 504 #填充section段固定头 505 section_head_bin = upg_bin[section_head_offset:section_head_offset+section_head_size] 506 section_head = hi_upg_section_head.from_buffer(section_head_bin) 507 section_head.image_id = image_id 508 section_head.struct_version = 0 509 section_head.param.hash_alg = 0 510 section_head.param.sign_alg = sign_alg 511 section_head.param.sign_param = 0 512 section_head.section_count = section_count 513 if section_count > 2: 514 sys.exit("[ERR]upg section count more than 2 FROM:%s"%os.path.realpath(__file__)) 515 elif section_count == 2: 516 section_head.section0_compress = section_compress_list[0] 517 section_head.section0_offset = section_offset_list[0] 518 section_head.section0_len = section_size_list[0] 519 section_head.section1_compress = section_compress_list[1] 520 section_head.section1_offset = section_offset_list[1] 521 section_head.section1_len = section_size_list[1] 522 elif section_count == 1: 523 section_head.section0_compress = section_compress_list[0] 524 section_head.section0_offset = section_offset_list[0] 525 section_head.section0_len = section_size_list[0] 526 section_head.section1_offset = 0 527 section_head.section1_len = 0 528 else: 529 section_head.section0_offset = 0 530 section_head.section0_len = 0 531 section_head.section1_offset = 0 532 section_head.section1_len = 0 533 upg_bin[section_head_offset:section_head_offset + section_head_size] = section_head_bin 534 535 #填充section段内容 536 i = 0 537 while i < section_count: 538 upg_bin[section_offset_list[i]:section_offset_list[i] + section_size_list[i]] = section_bin_list[i] 539 i = i + 1 540 541 #填充common段key 542 key_2_n = make_secure_key(alg_dir_path, common_head.param.sign_alg) 543 upg_bin[common_key_offset:common_key_offset + common_key_size] = key_2_n 544 545 #填充common段签名及section段签名(不同签名算法统一按最大值256Byte处理,填实际长度字节,多余的部分填0) 546 if sign_alg == 0x0: 547 (signature_1, signature_2) = make_rsa_pkcs_signature(alg_dir_path, upg_bin[common_head_offset:common_head_sign_offset], upg_bin[section_head_offset:section_head_offset+sizeof(hi_upg_section_head)]+upg_bin[upg_file_sign_offset+upg_file_sign_size:common_head.file_len]) 548 elif sign_alg == 0x1: 549 (signature_1, signature_2) = make_rsa_pss_signature(alg_dir_path, upg_bin[common_head_offset:common_head_sign_offset], upg_bin[section_head_offset:section_head_offset+sizeof(hi_upg_section_head)]+upg_bin[upg_file_sign_offset+upg_file_sign_size:common_head.file_len]) 550 elif sign_alg == 0x10: 551 (signature_1, signature_2) = make_ecc_secure_signature(alg_dir_path, upg_bin[common_head_offset:common_head_sign_offset], upg_bin[section_head_offset:section_head_offset+sizeof(hi_upg_section_head)]+upg_bin[upg_file_sign_offset+upg_file_sign_size:common_head.file_len]) 552 else: 553 (signature_1, signature_2) = make_sha256_unsecure_signature(upg_bin[common_head_offset:common_head_sign_offset], upg_bin[section_head_offset:section_head_offset+sizeof(hi_upg_section_head)]+upg_bin[upg_file_sign_offset+upg_file_sign_size:common_head.file_len]) 554 555 upg_bin[common_head_sign_offset:common_head_sign_offset+common_head_sign_size] = signature_1 556 upg_bin[upg_file_sign_offset:upg_file_sign_offset+upg_file_sign_size] = signature_2 557 558 return upg_bin 559 560def make_hupg(image_id, file_ver, encrypt_flag, kernel_file, normal_nv_file, image_file, alg_dir_path, max_size, sign_alg, chip_name, file_attr): 561 print('upg kernel file in:', kernel_file) 562 print('upg normal nv file in:', normal_nv_file) 563 print('upg file out:', image_file) 564 565 with open(kernel_file, 'rb') as fp: 566 kernel_bin = fp.read() 567 with open(normal_nv_file, 'rb') as fp: 568 nv_bin = fp.read() 569 570 section_bin_list = [] 571 section_bin_list.append(kernel_bin) 572 section_bin_list.append(nv_bin) 573 574 section_compress_list = [] 575 section_compress_list.append(0) 576 section_compress_list.append(0) 577 hupg_bin = make_upg_only(image_id, file_ver, encrypt_flag, 0xF0, section_bin_list, section_compress_list, alg_dir_path, max_size, sign_alg, chip_name, file_attr) 578 579 print_upg_info(image_file, hupg_bin) 580 #如果标记加密 581 unencrypted = 0x42 582 if encrypt_flag != unencrypted: 583 (filepath, tempfilename) = os.path.split(kernel_file) 584 (filename, extension) = os.path.splitext(tempfilename) 585 upg_unenrypt_file = os.path.join(filepath, '%s_unencrypt.bin'%filename) 586 with open(upg_unenrypt_file, 'wb+') as fp: 587 fp.write(hupg_bin) 588 589 aes_key_file = os.path.join(alg_dir_path, r'upg_aes_key.txt') 590 aes_encrypt_tool = os.path.join(alg_dir_path, r'sign_tool') 591 #双分区升级文件需要加密 592 src_file_len = len(hupg_bin) 593 if src_file_len < 0x1000: 594 sys.exit("\033[91m[ERR]upg size %d< 0x1000 FROM:%s\033[0m"%(src_file_len, os.path.realpath(__file__))) 595 aes_encrypt_bin(upg_unenrypt_file, image_file, 0x3C0, 0x1000, aes_key_file, aes_encrypt_tool) 596 else: 597 with open(image_file, 'wb+') as fp: 598 fp.write(hupg_bin) 599 return 600 601def make_compress_hupg(image_id, file_ver, encrypt_flag, upg_file, image_file, alg_dir_path, kernel_upg_max_size, sign_alg, lzma_tool, build_tmp, chip_name, file_attr): 602 print('compress upg file in: ', upg_file) 603 print('compress upg file out:', image_file) 604 605 (filepath, tempfilename) = os.path.split(upg_file) 606 (filename, extension) = os.path.splitext(tempfilename) 607 upg_lzma_file = os.path.join(build_tmp, '%s.lzma'%filename) 608 lzma_compress_bin(upg_file, upg_lzma_file, lzma_tool) 609 610 with open(upg_lzma_file, 'rb') as fp: 611 upg_lzma_file_bin = fp.read() 612 613 with open(upg_file, 'rb') as fp: 614 upg_bin = fp.read() 615 616 section_bin_list = [] 617 if encrypt_flag != 0x42: 618 upg_lzma_encrypt_file = os.path.join(build_tmp, '%s_encrypt.bin'%filename) 619 aes_key_file = os.path.join(alg_dir_path, r'upg_aes_key.txt') 620 aes_encrypt_tool = os.path.join(alg_dir_path, r'sign_tool') 621 #压缩文件文件需要加密 622 src_file_len = len(upg_lzma_file_bin) 623 if src_file_len < 0x13CD: 624 sys.exit("\033[91m[ERR]upg size %d< 0x13C0 FROM:%s\033[0m"%(src_file_len, os.path.realpath(__file__))) 625 aes_encrypt_bin(upg_lzma_file, upg_lzma_encrypt_file, 0xd, 0x13C0, aes_key_file, aes_encrypt_tool) 626 with open(upg_lzma_encrypt_file, 'rb') as fp: 627 upg_lzma_encrypt_file_bin = fp.read() 628 section_bin_list.append(upg_lzma_encrypt_file_bin) 629 else: 630 section_bin_list.append(upg_lzma_file_bin) 631 632 section_compress_list = [] 633 section_compress_list.append(1) 634 #计算压缩文件大小上限 635 upg_bin_len = len(upg_bin) 636 upg_align_len = (upg_bin_len//4096) * 4096 637 upg_len = upg_align_len 638 if upg_bin_len != upg_align_len: 639 upg_len = upg_align_len + 4096 640 max_compress_size = kernel_upg_max_size - upg_len 641 print("[upgbin-compressbin]0x%x-0x%x"%(upg_bin_len, max_compress_size)) 642 hupg_bin = make_upg_only(image_id, file_ver, encrypt_flag, 0xF0, section_bin_list, section_compress_list, alg_dir_path, max_compress_size, sign_alg, chip_name, file_attr) 643 print_upg_info(image_file, hupg_bin) 644 with open(image_file, 'wb+') as fp: 645 fp.write(hupg_bin) 646 return 647 648def make_hbin(flash_boot_file, factory_nv_file, normal_nv_file, upg_file, image_file): 649 print('hbin flash boot file in :', flash_boot_file) 650 print('hbin factory nv file in :', factory_nv_file) 651 print('hbin normal nv file in :', upg_file) 652 print('hbin upg file in :', factory_nv_file) 653 print('hbin file out :', image_file) 654 655 with open(flash_boot_file, 'rb') as fp: 656 flash_boot_bin = fp.read() 657 658 with open(factory_nv_file, 'rb') as fp: 659 factory_nv_bin = fp.read() 660 661 with open(normal_nv_file, 'rb') as fp: 662 normal_nv_bin = fp.read() 663 664 with open(upg_file, 'rb') as fp: 665 upg_file_bin = fp.read() 666 667 #Todo:从分表获取信息 668 boot_st_addr = 0 #BOOT 32KB 669 boot_size = 0x8000 670 ftm1_st_addr = 0x8000 #工厂区NV 4KB+4KB 671 ftm1_size = 0x1000 672 ftm2_st_addr = 0x9000 673 ftm2_size = 0x1000 674 nv_file_st_addr = 0xa000 #NV工作区 4KB+4KB 675 nv_file_size = 0x1000 676 nv_file_origin_st_addr = 0xc000 #NV工作区的原始备份 677 kernel_st_addr = 0xd000 #KernelA 912KB 678 679 bin_total_size = boot_size + ftm1_size + ftm2_size + nv_file_size + nv_file_size + nv_file_size + len(upg_file_bin) 680 681 boot_nv_kernel_bin = bytearray(bin_total_size) 682 boot_nv_kernel_bin[boot_st_addr:boot_st_addr + boot_size] = flash_boot_bin 683 boot_nv_kernel_bin[ftm1_st_addr:ftm1_st_addr + ftm1_size] = factory_nv_bin 684 #boot_nv_kernel_bin[ftm2_st_addr:ftm2_st_addr + ftm2_size] = factory_nv_bin 当前只放1份工厂区NV 685 boot_nv_kernel_bin[nv_file_st_addr:nv_file_st_addr + nv_file_size] = normal_nv_bin 686 boot_nv_kernel_bin[nv_file_origin_st_addr:nv_file_origin_st_addr + nv_file_size] = normal_nv_bin #NV区原始备份 687 boot_nv_kernel_bin[kernel_st_addr:kernel_st_addr + len(upg_file_bin)] = upg_file_bin 688 print_hbin_info(image_file, boot_nv_kernel_bin[kernel_st_addr:kernel_st_addr + len(upg_file_bin)], bin_total_size) 689 with open(image_file, "wb+") as fp: 690 fp.write(boot_nv_kernel_bin) 691 return 692 693def make_bootupg(image_id, file_ver, encrypt_flag, flash_boot_file, image_file, alg_dir_path, max_size, sign_alg, chip_name, file_attr): 694 print('boot upg file in:', flash_boot_file) 695 print('boot upg file out:', image_file) 696 with open(flash_boot_file, 'rb') as fp: 697 boot_bin = fp.read() 698 699 hupg_bin = make_upg_boot_only(image_id, file_ver, encrypt_flag, 0xE1, boot_bin, alg_dir_path, max_size, sign_alg, chip_name, file_attr) 700 print_upg_info(image_file, hupg_bin) 701 with open(image_file, 'wb+') as fp: 702 fp.write(hupg_bin) 703 return 704 705#配置romboot下用法boot升级文件的填充字段放到section前面 706def make_upg_boot_only(image_id, file_ver, encrypt_flag, file_type, section_bin, alg_dir_path, max_size, sign_alg, chip_name, file_attr): 707 temp_offset = [0] 708 709 #common固定头大小偏移 710 (common_head_offset, common_head_size) = make_part_offset_size(temp_offset, sizeof(hi_upg_common_head)) 711 print('[common_head_offset=%d][common_head_size=%d]'%(common_head_offset, common_head_size)) 712 713 #common密钥区大小偏移、固定头签名大小偏移 714 if sign_alg < 0x10: 715 #RSA2048 716 (common_key_offset, common_key_size) = make_part_offset_size(temp_offset, sizeof(upg_rsa_key)) 717 (common_head_sign_offset, common_head_sign_size) = make_part_offset_size(temp_offset, sizeof(upg_rsa_sign)) 718 elif sign_alg == 0x10: 719 #ECDSA256 720 (common_key_offset, common_key_size) = make_part_offset_size(temp_offset, sizeof(upg_ecc_key)) 721 (common_head_sign_offset, common_head_sign_size) = make_part_offset_size(temp_offset, sizeof(upg_ecc_sign)) 722 else: 723 #SHA256 724 (common_key_offset, common_key_size) = make_part_offset_size(temp_offset, sizeof(upg_sha256_key)) 725 (common_head_sign_offset, common_head_sign_size) = make_part_offset_size(temp_offset, sizeof(upg_sha256_sign)) 726 print('[common_key_offset=%d][common_key_size=%d]'%(common_key_offset, common_key_size)) 727 print('[common_head_sign_offset=%d][common_head_sign_size=%d]'%(common_head_sign_offset, common_head_sign_size)) 728 #section固定头大小偏移 729 (section_head_offset, section_head_size) = make_part_offset_size(temp_offset, sizeof(hi_upg_section_head)) 730 print('[section_head_offset=%d][section_head_size=%d]'%(section_head_offset, section_head_size)) 731 #section签名大小偏移、秘钥信息。签名算法不同,填充大小不同 732 if sign_alg < 0x10: 733 (upg_file_sign_offset, upg_file_sign_size) = make_part_offset_size(temp_offset, sizeof(upg_rsa_sign)) 734 elif sign_alg == 0x10: 735 (upg_file_sign_offset, upg_file_sign_size) = make_part_offset_size(temp_offset, sizeof(upg_ecc_sign)) 736 else: 737 (upg_file_sign_offset, upg_file_sign_size) = make_part_offset_size(temp_offset, sizeof(upg_sha256_sign)) 738 print('[upg_file_sign_offset=%d][upg_file_sign_size=%d]'%(upg_file_sign_offset, upg_file_sign_size)) 739 #填充大小和偏移 740 temp_size_1 = temp_offset[0] + len(section_bin) 741 temp_size_2 = temp_size_1//16 742 temp_size_2 = temp_size_2*16 743 padding_size = temp_size_1 - temp_size_2 744 if temp_size_1 == temp_size_2: 745 padding_size = 0 746 else: 747 padding_size = temp_size_2 + 16 - temp_size_1 748 749 (padding_offset, padding_size) = make_part_offset_size(temp_offset, padding_size) 750 print('[padding_offset=%d][padding_size=%d]'%(padding_offset, padding_size)) 751 752 #镜像大小和偏移 753 (section_offset, section_size) = make_part_offset_size(temp_offset, len(section_bin))#BOOT部分大小 754 755 #初始化upg_bin 756 upg_bin = bytearray(temp_offset[0]) 757 758 #升级文件大小上限从分区获取 759 if len(upg_bin) > max_size: 760 sys.exit("\033[91m[ERR]upg boot size>%dKB FROM:%s\033[0m"%(max_size/1024, os.path.realpath(__file__))) 761 762 #填充common段固定头 763 common_head_bin = upg_bin[common_head_offset:common_head_offset + common_head_size] 764 common_head = hi_upg_common_head.from_buffer(common_head_bin) 765 common_head.image_id = image_id 766 common_head.struct_version = 0 767 common_head.section_offset = section_head_offset 768 common_head.section_len = len(upg_bin) - section_head_offset 769 common_head.file_type = file_type 770 common_head.file_version = file_ver 771 common_head.encrypt_flag = encrypt_flag 772 common_head.file_attr = file_attr 773 common_head.file_len = len(upg_bin) 774 common_head.key_len = common_key_size 775 common_head.param.hash_alg = 0 776 common_head.param.sign_alg = sign_alg 777 common_head.param.sign_param = 0 778 #common_head.aes_key[16] = 779 #common_head.aes_iv[16] = 780 #image_id struct_version section_offset section_offset 781 user_info_offset = sizeof(c_int) + sizeof(c_int) + sizeof(c_int) + sizeof(c_int) 782 common_head_bin[user_info_offset : (user_info_offset + sizeof(hi_upg_user_info))] = USER_INFO.fill_user_info(chip_name) 783 upg_bin[common_head_offset:common_head_offset+common_head_size] = common_head_bin 784 785 #填充section段固定头 786 section_head_bin = upg_bin[section_head_offset:section_head_offset+section_head_size] 787 section_head = hi_upg_section_head.from_buffer(section_head_bin) 788 section_head.image_id = image_id 789 section_head.struct_version = 0 790 section_head.param.hash_alg = 0 791 section_head.param.sign_alg = sign_alg 792 section_head.param.sign_param = 0 793 section_head.section_count = 1 794 section_head.section0_compress = 0 795 section_head.section0_offset = section_offset 796 section_head.section0_len = section_size 797 section_head.section1_compress = 0 798 section_head.section1_offset = 0 799 section_head.section1_len = 0 800 upg_bin[section_head_offset:section_head_offset + section_head_size] = section_head_bin 801 802 #填充section段内容 803 upg_bin[section_offset:section_offset + section_size] = section_bin 804 805 #填充common段key 806 key_2_n = make_secure_key(alg_dir_path, common_head.param.sign_alg) 807 upg_bin[common_key_offset:common_key_offset + common_key_size] = key_2_n 808 809 #填充common段签名及section段签名 810 if sign_alg == 0x0: 811 (signature_1, signature_2) = make_rsa_pkcs_signature(alg_dir_path, upg_bin[common_head_offset:common_head_sign_offset], upg_bin[section_head_offset:section_head_offset+sizeof(hi_upg_section_head)]+upg_bin[upg_file_sign_offset+upg_file_sign_size:common_head.file_len]) 812 elif sign_alg == 0x1: 813 (signature_1, signature_2) = make_rsa_pss_signature(alg_dir_path, upg_bin[common_head_offset:common_head_sign_offset], upg_bin[section_head_offset:section_head_offset+sizeof(hi_upg_section_head)]+upg_bin[upg_file_sign_offset+upg_file_sign_size:common_head.file_len]) 814 elif sign_alg == 0x10: 815 (signature_1, signature_2) = make_ecc_secure_signature(alg_dir_path, upg_bin[common_head_offset:common_head_sign_offset], upg_bin[section_head_offset:section_head_offset+sizeof(hi_upg_section_head)]+upg_bin[upg_file_sign_offset+upg_file_sign_size:common_head.file_len]) 816 else: 817 (signature_1, signature_2) = make_sha256_unsecure_signature(upg_bin[common_head_offset:common_head_sign_offset], upg_bin[section_head_offset:section_head_offset+sizeof(hi_upg_section_head)]+upg_bin[upg_file_sign_offset+upg_file_sign_size:common_head.file_len]) 818 819 upg_bin[common_head_sign_offset:common_head_sign_offset+common_head_sign_size] = signature_1 820 upg_bin[upg_file_sign_offset:upg_file_sign_offset+upg_file_sign_size] = signature_2 821 822 return upg_bin