• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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