rjw | 1f88458 | 2022-01-06 17:20:42 +0800 | [diff] [blame^] | 1 | #!/usr/bin/python |
| 2 | # -*- coding: utf8 -*- |
| 3 | |
| 4 | import json |
| 5 | import struct |
| 6 | import sys |
| 7 | import binascii |
| 8 | import cryptoSB |
| 9 | import copy |
| 10 | |
| 11 | from jsoncomment import JsonComment |
| 12 | |
| 13 | __Align = 16 |
| 14 | __Align_16_en = 0 |
| 15 | |
| 16 | __TEST = 0 |
| 17 | |
| 18 | __Align_pub_key_apend = 512 |
| 19 | __Align_sign_size = 512 |
| 20 | |
| 21 | g_magic_size = 8 |
| 22 | g_total_len_size = 4 |
| 23 | g_bl_version_size = 4 |
| 24 | g_img_number_size = 4 |
| 25 | g_ls_cmd_number_size = 4 |
| 26 | g_mi_header_info_size = (g_magic_size + g_total_len_size + g_bl_version_size + g_img_number_size + g_ls_cmd_number_size) |
| 27 | |
| 28 | g_img_header_size = 96 |
| 29 | g_ls_cmd_size = 8 |
| 30 | |
| 31 | g_img_oneoffset_table_size = 4 |
| 32 | g_img_onehash_table_size = 64 |
| 33 | |
| 34 | g_public_key_size = __Align_pub_key_apend |
| 35 | g_rsa_n_size = __Align_pub_key_apend |
| 36 | g_sbc_auth_inf_size = 4 |
| 37 | g_sbc_auth_key_hash_size = 4 |
| 38 | g_sbc_auth_alg_size = 4 |
| 39 | g_sbc_auth_alg_hash_size = 4 |
| 40 | g_sbc_rsa_pad_sel_size = 4 |
| 41 | g_sbc_pub_key_len_size = 4 |
| 42 | g_sbc_size = (g_public_key_size + g_rsa_n_size + g_sbc_auth_inf_size + g_sbc_auth_key_hash_size + g_sbc_auth_alg_size + g_sbc_auth_alg_hash_size + g_sbc_rsa_pad_sel_size + g_sbc_pub_key_len_size) |
| 43 | |
| 44 | g_boot_hash_size = 64 |
| 45 | g_signature_size = __Align_sign_size |
| 46 | g_auth_size = (g_boot_hash_size + g_signature_size) |
| 47 | |
| 48 | g_ck_magic_size = 16 |
| 49 | g_ck_soc_id_size = 32 |
| 50 | g_ck_pub_key_size = __Align_pub_key_apend |
| 51 | g_ck_auth_algo_size = 4 |
| 52 | g_ck_put_key_len_size = 4 |
| 53 | g_ck_signature_size = __Align_sign_size |
| 54 | g_ck_size = (g_ck_magic_size + g_ck_soc_id_size + g_ck_pub_key_size + g_ck_auth_algo_size + g_ck_put_key_len_size + g_ck_signature_size) |
| 55 | |
| 56 | def to_int(s): |
| 57 | if isinstance(s, (str, unicode)): |
| 58 | return int(s, 0) |
| 59 | else: |
| 60 | return s |
| 61 | |
| 62 | def byte_to_int(bytes): |
| 63 | result = 0 |
| 64 | |
| 65 | for b in bytes: |
| 66 | result = result*256 + ord(b) |
| 67 | |
| 68 | return result |
| 69 | |
| 70 | def read_desc(mi_desc_fn): |
| 71 | #desc = json.load(open(mi_desc_fn)) |
| 72 | |
| 73 | parser = JsonComment(json) |
| 74 | desc = parser.loads(open(mi_desc_fn).read()) |
| 75 | |
| 76 | for img in desc['images']: |
| 77 | img['img_enc_alg'] = to_int(img['img_enc_alg']) |
| 78 | img['img_enc_inf'] = to_int(img['img_enc_inf']) |
| 79 | |
| 80 | '''0627 remove int assign avoid key start is (0x00..)''' |
| 81 | #img['img_iv'] = to_int(img['img_iv']) |
| 82 | |
| 83 | return desc |
| 84 | |
| 85 | |
| 86 | def gen_ver_magic(major, minor, revision): |
| 87 | major = to_int(major) |
| 88 | minor = to_int(minor) |
| 89 | revision = to_int(revision) |
| 90 | |
| 91 | x = major ^ 0xaa |
| 92 | y = minor ^ 0x55 |
| 93 | z = revision ^ 0x99 |
| 94 | checksum = (x + y + z) & 0xff |
| 95 | |
| 96 | return (major << 0) | (minor << 8) | (revision << 16) | (checksum << 24) |
| 97 | |
| 98 | def my_gen_ver_magic(major, minor, revision): |
| 99 | major = to_int(major) |
| 100 | minor = to_int(minor) |
| 101 | revision = to_int(revision) |
| 102 | |
| 103 | x = major ^ 0xaa |
| 104 | y = minor ^ 0x55 |
| 105 | z = revision ^ 0x99 |
| 106 | checksum = (x + y + z) & 0xff |
| 107 | |
| 108 | highmagic = byte_to_int(b'\x27\x21\xca\xfe') |
| 109 | #print(hex(highmagic)) |
| 110 | |
| 111 | return (major << 0) | (minor << 8) | (revision << 16) | (checksum << 24), highmagic |
| 112 | |
| 113 | def my_gen_mtk_magic(magic): |
| 114 | magic_str = my_to_bytes(magic, g_magic_size, endianess='little') |
| 115 | |
| 116 | lowmagic = byte_to_int(magic_str[4:8]) |
| 117 | highmagic = byte_to_int(magic_str[0:4]) |
| 118 | |
| 119 | return lowmagic, highmagic |
| 120 | |
| 121 | def pad_to_align(align, current_size): |
| 122 | if not align: |
| 123 | return '' |
| 124 | |
| 125 | pad_size = (align - current_size % align) % align |
| 126 | pad = '\0' * pad_size |
| 127 | |
| 128 | return pad |
| 129 | |
| 130 | |
| 131 | def dump(data): |
| 132 | for i in range(0, len(data)): |
| 133 | if(i%16 == 0): |
| 134 | print("[%04X]" % i), |
| 135 | |
| 136 | print("%02x" % ord(data[i])), |
| 137 | if(((i+1)%16) == 0): |
| 138 | print |
| 139 | |
| 140 | def pack_load_script(mi_desc): |
| 141 | ls_script = [] |
| 142 | reserved = 0 |
| 143 | images = mi_desc['images'] |
| 144 | img_num = len(images) |
| 145 | |
| 146 | ls_cmds = mi_desc['load_srcipt_cmd'] |
| 147 | ls_cmds_num = len(ls_cmds) |
| 148 | #print("ls_cmds_num: %d" %ls_cmds_num) |
| 149 | |
| 150 | for i in range(ls_cmds_num): |
| 151 | ls_cmd = ls_cmds[i] |
| 152 | cmd = ls_cmd['cmd'] |
| 153 | |
| 154 | if cmd == "LOAD": |
| 155 | cmd_id = 0 |
| 156 | img_file = ls_cmd['img_file'] |
| 157 | addr = to_int(ls_cmd['addr']) |
| 158 | |
| 159 | img_id = -1 |
| 160 | for j in range(img_num): |
| 161 | img = images[j] |
| 162 | img_binary_name = img['img_file'] |
| 163 | if img_file == img_binary_name: |
| 164 | img_id = j |
| 165 | break |
| 166 | |
| 167 | if img_id == -1: |
| 168 | print("Please check img file name") |
| 169 | return |
| 170 | |
| 171 | packed_cmd = struct.pack('<BBHI', cmd_id, img_id, reserved, addr) |
| 172 | #dump(packed_cmd) |
| 173 | #print |
| 174 | elif cmd == "MCU-ENTRY": |
| 175 | cmd_id = 2 |
| 176 | mcu_id = ls_cmd['mcu_id'] |
| 177 | addr = to_int(ls_cmd['addr']) |
| 178 | packed_cmd = struct.pack('<BBHI', cmd_id, mcu_id, reserved, addr) |
| 179 | #dump(packed_cmd) |
| 180 | #print |
| 181 | elif cmd == "MCU_RESET-ENTRY": |
| 182 | cmd_id = 1 |
| 183 | mcu_id = ls_cmd['mcu_id'] |
| 184 | addr = to_int(ls_cmd['addr']) |
| 185 | packed_cmd = struct.pack('<BBHI', cmd_id, mcu_id, reserved, addr) |
| 186 | #dump(packed_cmd) |
| 187 | #print |
| 188 | else: |
| 189 | print("unknown command: %s" %cmd) |
| 190 | return |
| 191 | |
| 192 | ls_script += packed_cmd |
| 193 | |
| 194 | #print("load script:") |
| 195 | #dump(ls_script) |
| 196 | |
| 197 | return ls_script |
| 198 | |
| 199 | def rsa_data_parser(mi_desc, sbc_rsa_pad_sel): |
| 200 | rsa_dict = {"n":'', "e":'', "d":''} |
| 201 | rsa_parse = [] |
| 202 | |
| 203 | if(sbc_rsa_pad_sel == 0): |
| 204 | rsa_d = mi_desc['rsa_data'] |
| 205 | rsa_data = rsa_d[0] |
| 206 | |
| 207 | rsa_dict['n'] = rsa_data['n'] |
| 208 | rsa_dict['e'] = rsa_data['e'] |
| 209 | rsa_dict['d'] = rsa_data['d'] |
| 210 | rsa_parse.append(rsa_dict) |
| 211 | #print(rsa_parse) |
| 212 | |
| 213 | #rsa_parse.append(rsa_data['n']) |
| 214 | #rsa_parse.append(rsa_data['e']) |
| 215 | #rsa_parse.append(rsa_data['d']) |
| 216 | rsa_parse.append(rsa_data['msg2hash']) |
| 217 | rsa_parse.append(rsa_data['signvalue']) |
| 218 | rsa_parse.append(rsa_data['shafunc']) |
| 219 | rsa_parse.append(rsa_data['msgtest']) |
| 220 | print("dump rsa_data_parser") |
| 221 | #print(rsa_parse) |
| 222 | #print(rsa_parse[0]) |
| 223 | else: |
| 224 | rsa_d = mi_desc['rsa_data_pss'] |
| 225 | rsa_data = rsa_d[0] |
| 226 | |
| 227 | rsa_dict['n'] = rsa_data['n'] |
| 228 | rsa_dict['e'] = rsa_data['e'] |
| 229 | rsa_dict['d'] = rsa_data['d'] |
| 230 | rsa_parse.append(rsa_dict) |
| 231 | |
| 232 | rsa_parse.append(rsa_data['msg2hash']) |
| 233 | rsa_parse.append(rsa_data['signvalue']) |
| 234 | rsa_parse.append(rsa_data['salt']) |
| 235 | rsa_parse.append(rsa_data['shafunc']) |
| 236 | rsa_parse.append(rsa_data['msgtest']) |
| 237 | print("dump rsa_data_parser") |
| 238 | print(rsa_parse) |
| 239 | |
| 240 | return rsa_parse |
| 241 | |
| 242 | def ck_rsa_data_parser(mi_desc, sbc_rsa_pad_sel): |
| 243 | rsa_dict = {"n":'', "e":'', "d":''} |
| 244 | rsa_parse = [] |
| 245 | |
| 246 | if(sbc_rsa_pad_sel == 0): |
| 247 | rsa_d = mi_desc['ck_rsa_data'] |
| 248 | rsa_data = rsa_d[0] |
| 249 | |
| 250 | rsa_dict['n'] = rsa_data['n'] |
| 251 | rsa_dict['e'] = rsa_data['e'] |
| 252 | rsa_dict['d'] = rsa_data['d'] |
| 253 | rsa_parse.append(rsa_dict) |
| 254 | #print(rsa_parse) |
| 255 | |
| 256 | #rsa_parse.append(rsa_data['n']) |
| 257 | #rsa_parse.append(rsa_data['e']) |
| 258 | #rsa_parse.append(rsa_data['d']) |
| 259 | rsa_parse.append(rsa_data['msg2hash']) |
| 260 | rsa_parse.append(rsa_data['signvalue']) |
| 261 | rsa_parse.append(rsa_data['shafunc']) |
| 262 | rsa_parse.append(rsa_data['msgtest']) |
| 263 | print("dump rsa_data_parser") |
| 264 | #print(rsa_parse) |
| 265 | #print(rsa_parse[0]) |
| 266 | else: |
| 267 | rsa_d = mi_desc['ck_rsa_data_pss'] |
| 268 | rsa_data = rsa_d[0] |
| 269 | |
| 270 | rsa_dict['n'] = rsa_data['n'] |
| 271 | rsa_dict['e'] = rsa_data['e'] |
| 272 | rsa_dict['d'] = rsa_data['d'] |
| 273 | rsa_parse.append(rsa_dict) |
| 274 | |
| 275 | rsa_parse.append(rsa_data['msg2hash']) |
| 276 | rsa_parse.append(rsa_data['signvalue']) |
| 277 | rsa_parse.append(rsa_data['salt']) |
| 278 | rsa_parse.append(rsa_data['shafunc']) |
| 279 | rsa_parse.append(rsa_data['msgtest']) |
| 280 | print("dump rsa_data_parser") |
| 281 | print(rsa_parse) |
| 282 | |
| 283 | return rsa_parse |
| 284 | |
| 285 | def my_pack_images(mi_desc, privk, enckey, align=None, img_dir=''): |
| 286 | ''' |
| 287 | mipack_file |
| 288 | mi_header_info |
| 289 | u32 magic |
| 290 | u32 total_len |
| 291 | u32 bl_version |
| 292 | u32 img_number (N) |
| 293 | u32 load_script_cmd_number (M) |
| 294 | |
| 295 | img_info[1]~img_info[N] |
| 296 | u32 img_length |
| 297 | u32 img_offset |
| 298 | 64Byes img_hash |
| 299 | u32 img_enc_inf |
| 300 | u32 img_enc_alg |
| 301 | 16Bytes img_iv |
| 302 | |
| 303 | load_script_cmd[1]~load_script_cmd[M] |
| 304 | u64 cmd |
| 305 | |
| 306 | sbc data |
| 307 | 512Bytes sbc_pub_key |
| 308 | 512Bytes sbc_rsa_n |
| 309 | u32 sbc_auth_info |
| 310 | u32 sbc_key_hash |
| 311 | u32 sbc_auth_algo_dsa |
| 312 | u32 sbc_auth_algo_hash |
| 313 | u32 sbc_rsa_pad_sel |
| 314 | u32 sbc_pub_key_len |
| 315 | |
| 316 | auth data |
| 317 | 64Bytes boothash |
| 318 | 512Bytes signature |
| 319 | |
| 320 | [img binary 1] |
| 321 | ... |
| 322 | [img binary 1] |
| 323 | ''' |
| 324 | |
| 325 | key_mode = 0 |
| 326 | |
| 327 | mi_header_struct = struct.Struct('<IIIIII') |
| 328 | sbc_struct = struct.Struct('<IIIIII') |
| 329 | ck_struct = struct.Struct('<II') |
| 330 | |
| 331 | |
| 332 | #run hash |
| 333 | hash = cryptoSB.HASH() |
| 334 | |
| 335 | # ver_magic |
| 336 | #version = mi_desc['version'] |
| 337 | #major, minor, revision = version.split('.') |
| 338 | #ver_magic_l, ver_magic_h = my_gen_ver_magic(major, minor, revision) |
| 339 | |
| 340 | ver_magic_l, ver_magic_h = my_gen_mtk_magic(to_int(mi_desc['magic_num'])) |
| 341 | |
| 342 | # bl region |
| 343 | bl_version = mi_desc['bl_version'] |
| 344 | images = mi_desc['images'] |
| 345 | img_num = len(images) |
| 346 | ls_cmds = mi_desc['load_srcipt_cmd'] |
| 347 | ls_cmds_num = len(ls_cmds) |
| 348 | |
| 349 | '''size of bl + imgl + sbc + auth''' |
| 350 | # Fixed size section: mi_header, sbc data, auth data |
| 351 | # Non-fixed size section: img_info, load script |
| 352 | bl_total_len = g_mi_header_info_size + g_sbc_size + g_auth_size |
| 353 | #bl_total_len = g_mi_header_info_size + g_sbc_size + g_auth_size + g_ck_size |
| 354 | bl_total_len += img_num * g_img_header_size |
| 355 | bl_total_len += ls_cmds_num * g_ls_cmd_size |
| 356 | |
| 357 | |
| 358 | #print("==== multi-image header size ====") |
| 359 | #print("g_mi_header_info_size=%d, g_sbc_size=%d, g_auth_size=%d, bl_total_len = %d" %(g_mi_header_info_size, g_sbc_size, g_auth_size, bl_total_len)) |
| 360 | |
| 361 | #img_header_table = [] |
| 362 | img_headers = [] |
| 363 | bins = [] |
| 364 | sbc_region = [] |
| 365 | hashtable = [] |
| 366 | imagetmp = [[], [], [], [], [], [], [], [], [], []] |
| 367 | packtmp = [] |
| 368 | blh_hash = [] |
| 369 | signaturelist = [] |
| 370 | ck_region = [] |
| 371 | cksignaturelist = [] |
| 372 | |
| 373 | imagesize = [] |
| 374 | |
| 375 | |
| 376 | sbc_auth_alg = mi_desc['sbc_auth_alg'] |
| 377 | sbc_rsa_pad_sel = mi_desc['sbc_rsa_pad_sel'] |
| 378 | ''' parer rsa test pattern ''' |
| 379 | rsa_parse = rsa_data_parser(mi_desc, sbc_rsa_pad_sel) |
| 380 | |
| 381 | # sbc region |
| 382 | ##pub_key = to_int(mi_desc['public_key']) |
| 383 | ##public_key = my_binify(pub_key) |
| 384 | '''20180627 remove int assign avoid key start is (0x00..)''' |
| 385 | pub_key = (mi_desc['public_key']) |
| 386 | public_key = cryptoSB.strip_key(pub_key) |
| 387 | pubk = b'\x04' + public_key |
| 388 | |
| 389 | rsa_e = cryptoSB.my_a2b_hex(rsa_parse[0]['e']) |
| 390 | rsa_n = cryptoSB.my_a2b_hex(rsa_parse[0]['n']) |
| 391 | if((sbc_auth_alg == 0) or (sbc_auth_alg == 1) or (sbc_auth_alg == 2)): |
| 392 | public_key_append = my_pad_to_align(public_key, __Align_pub_key_apend) |
| 393 | sbc_region.append(public_key_append) |
| 394 | |
| 395 | #sbc_rsa_n = (mi_desc['sbc_rsa_n']) |
| 396 | #rsa_modulus = cryptoSB.strip_key(sbc_rsa_n) |
| 397 | rsa_modulus_append = my_pad_to_align(rsa_n, __Align_pub_key_apend) |
| 398 | sbc_region.append(rsa_modulus_append) |
| 399 | elif((sbc_auth_alg == 3) or (sbc_auth_alg == 4) or (sbc_auth_alg == 5)): |
| 400 | rsa_e_append = my_pad_to_align(rsa_e, __Align_pub_key_apend) |
| 401 | sbc_region.append(rsa_e_append) |
| 402 | rsa_n_append = my_pad_to_align(rsa_n, __Align_pub_key_apend) |
| 403 | sbc_region.append(rsa_n_append) |
| 404 | |
| 405 | |
| 406 | #print("======= sbc region =========") |
| 407 | sbc_auth_inf = mi_desc['sbc_auth_inf'] |
| 408 | #print("sbc_auth_inf = 0x%x" %sbc_auth_inf) |
| 409 | sbc_key_hash = mi_desc['sbc_key_hash'] |
| 410 | sbc_auth_alg = mi_desc['sbc_auth_alg'] |
| 411 | #print("sbc_auth_alg = 0x%x" %sbc_auth_alg) |
| 412 | sbc_auth_alg_hash = mi_desc['sbc_auth_alg_hash'] |
| 413 | sbc_rsa_pad_sel = mi_desc['sbc_rsa_pad_sel'] |
| 414 | sbc_pub_key_len = mi_desc['sbc_pub_key_len'] |
| 415 | sbc = sbc_struct.pack(sbc_auth_inf, sbc_key_hash, sbc_auth_alg, sbc_auth_alg_hash, sbc_rsa_pad_sel, sbc_pub_key_len) |
| 416 | sbc_region.append(sbc) |
| 417 | |
| 418 | #print("======= ck region =========") |
| 419 | ck_mg = (mi_desc['ck_magic_num']) |
| 420 | ck_magic = cryptoSB.strip_key(ck_mg) |
| 421 | ck_region.append(ck_magic) |
| 422 | ck_sid = (mi_desc['ck_soc_id']) |
| 423 | ck_soc_id = cryptoSB.strip_key(ck_sid) |
| 424 | ck_region.append(ck_soc_id) |
| 425 | ck_pkey = (mi_desc['ck_pub_key']) |
| 426 | |
| 427 | ck_pub_key = cryptoSB.strip_key(ck_pkey) |
| 428 | ck_pub_key_append = my_pad_to_align(ck_pub_key, __Align_pub_key_apend) |
| 429 | ck_region.append(ck_pub_key_append) |
| 430 | ck_pubk = b'\x04' + ck_pub_key |
| 431 | |
| 432 | ck_rsa_n = (mi_desc['ck_rsa_n']) |
| 433 | ck_rsa_modulus = cryptoSB.strip_key(ck_rsa_n) |
| 434 | ck_rsa_modulus_append = my_pad_to_align(ck_rsa_modulus, __Align_pub_key_apend) |
| 435 | ck_region.append(ck_rsa_modulus_append) |
| 436 | |
| 437 | ck_auth_algo = mi_desc['ck_auth_algo'] |
| 438 | ck_pub_key_len = mi_desc['ck_pub_key_len'] |
| 439 | ck = ck_struct.pack(ck_auth_algo, ck_pub_key_len) |
| 440 | ck_region.append(ck) |
| 441 | |
| 442 | ck_en = mi_desc['change_key_en'] |
| 443 | sign_ck_priv_key = mi_desc['sign_ck_priv_key'] |
| 444 | signckprivk = cryptoSB.strip_key(sign_ck_priv_key) |
| 445 | |
| 446 | # pad before 1st image |
| 447 | |
| 448 | #pad = pad_to_align(64, expected_size) |
| 449 | #bins.append(pad) |
| 450 | #expected_size += len(pad) |
| 451 | |
| 452 | |
| 453 | # images |
| 454 | # 512 bytes aligned (20200310) |
| 455 | img_offset = (bl_total_len + 511) & (~511) |
| 456 | img_offset_table = [] |
| 457 | |
| 458 | for i in range(img_num): |
| 459 | #print("\n\n======== Start image step: =========") |
| 460 | |
| 461 | |
| 462 | img = images[i] |
| 463 | img_file = img['img_file'] |
| 464 | img_enc_inf = img['img_enc_inf'] |
| 465 | img_enc_alg = img['img_enc_alg'] |
| 466 | #print("img_enc_inf=0x%x" %img_enc_inf) |
| 467 | |
| 468 | bin = open(img_dir + '/' + img_file, 'rb').read() |
| 469 | |
| 470 | iv_int = img['img_iv'] |
| 471 | #iv = my_binify(iv_int) |
| 472 | '''0627 remove int assign avoid key start is (0x00..)''' |
| 473 | iv = cryptoSB.strip_key(iv_int) |
| 474 | iv0= int(iv[0:4].encode('hex'), 16) |
| 475 | iv1= int(iv[4:8].encode('hex'), 16) |
| 476 | iv2= int(iv[8:12].encode('hex'), 16) |
| 477 | iv3= int(iv[12:16].encode('hex'), 16) |
| 478 | #print type(iv) |
| 479 | #print("IV:") |
| 480 | #cryptoSB.dump(iv) |
| 481 | |
| 482 | |
| 483 | if(img_enc_inf == 1): |
| 484 | '''image encrypt''' |
| 485 | out = cryptoSB.my_img_enc(bin, enckey, iv, img_enc_alg, __Align) |
| 486 | bins.append(out) |
| 487 | #bins = out |
| 488 | elif(img_enc_inf == 2): |
| 489 | '''image encrypt''' |
| 490 | out = cryptoSB.my_img_enc(bin, enckey, iv, img_enc_alg, __Align) |
| 491 | bins.append(out) |
| 492 | #bins = out |
| 493 | else: |
| 494 | '''plaintext image''' |
| 495 | out = my_pad_to_align(bin, __Align) |
| 496 | bins.append(out) |
| 497 | #bins = out |
| 498 | |
| 499 | # binary length should be 16 bytes aligned |
| 500 | length = len(out) |
| 501 | |
| 502 | imagesize.append(length) |
| 503 | #print("") |
| 504 | #print("image[%d] offset : 0x%x" %(i, img_offset)) |
| 505 | #print("image[%d] size : 0x%x" %(i, imagesize[i])) |
| 506 | |
| 507 | imagetmp[i] = copy.copy(bins) |
| 508 | |
| 509 | img_str = ''.join(bins) |
| 510 | #print type(img_str) |
| 511 | #print("========= image[%d] binary ==========" %i) |
| 512 | #cryptoSB.dump(img_str) |
| 513 | |
| 514 | |
| 515 | # hash each (image header + image binary) |
| 516 | #print('') |
| 517 | #print("========= image[%d] binary hash ==========" %i) |
| 518 | hashvalue = cryptoSB.sb_hash(img_str, sbc_auth_alg_hash) |
| 519 | imghash = my_pad_to_align(hashvalue, g_boot_hash_size) |
| 520 | #cryptoSB.dump(imghash) |
| 521 | |
| 522 | # img_header |
| 523 | img_hdr = struct.pack('<II', |
| 524 | length, |
| 525 | img_offset) |
| 526 | img_hdr += "".join(imghash) |
| 527 | '''20180719 fix IV order fail''' |
| 528 | img_hdr += struct.pack('<II16s', |
| 529 | img_enc_inf, |
| 530 | img_enc_alg, |
| 531 | iv) |
| 532 | |
| 533 | |
| 534 | img_offset_table.append(str(img_offset)) |
| 535 | length = (length + 511) & (~511) |
| 536 | img_offset += length |
| 537 | #img_offset_table.append(my_to_bytes(img_offset, 4, endianess='little')) |
| 538 | |
| 539 | #print("\n=====>") |
| 540 | #print("image[%d] header info :" %i) |
| 541 | #cryptoSB.dump(img_hdr) |
| 542 | img_headers.append(img_hdr) |
| 543 | |
| 544 | #img_headers.remove(img_hdr) |
| 545 | while len(bins) > 0: |
| 546 | bins.pop() |
| 547 | |
| 548 | |
| 549 | #print("\n\nSTART to pack all sections ...") |
| 550 | pack = [] |
| 551 | |
| 552 | #print("======== append mi_header info ==========") |
| 553 | total_len = int(img_offset_table[img_num-1]) + int(imagesize[img_num-1]) |
| 554 | |
| 555 | mi_header = mi_header_struct.pack( |
| 556 | ver_magic_l, |
| 557 | ver_magic_h, |
| 558 | total_len, |
| 559 | bl_version, |
| 560 | img_num, |
| 561 | ls_cmds_num) |
| 562 | |
| 563 | |
| 564 | pack.append(mi_header) |
| 565 | |
| 566 | # append image info |
| 567 | for i in range(img_num): |
| 568 | pack += img_headers[i] |
| 569 | |
| 570 | |
| 571 | ls_script = pack_load_script(mi_desc) |
| 572 | if ls_script == None: |
| 573 | print("pack_load_script fail") |
| 574 | return |
| 575 | |
| 576 | # append load script |
| 577 | pack += ls_script |
| 578 | |
| 579 | # append sbc data |
| 580 | pack += sbc_region |
| 581 | |
| 582 | # for easy view. please remove it while release final |
| 583 | '''align for (bl + imgl + sbc)''' |
| 584 | if(__Align_16_en == 1): |
| 585 | padnum = pad_to_align(16, len(''.join(pack))) |
| 586 | pack.append(padnum) |
| 587 | |
| 588 | #print("======== append mi_header hash: ==========") |
| 589 | bl_header = ''.join(pack) |
| 590 | #cryptoSB.dump(bl_header) |
| 591 | blh = copy.copy(bl_header) |
| 592 | boothash = cryptoSB.sb_hash(blh, sbc_auth_alg_hash) |
| 593 | boothash_append = my_pad_to_align(boothash, g_boot_hash_size) |
| 594 | #cryptoSB.dump(boothash_append) |
| 595 | blh_hash.append(boothash_append) |
| 596 | |
| 597 | # append hash |
| 598 | pack += blh_hash |
| 599 | |
| 600 | #print("======== append mi_header signature: =========") |
| 601 | #privk = "\xc1\xbe\xe4\xfa\x86\xaf\x86\x84\x67\x7c\xae\xee\xa8\x8a\xb0\x72\x3e\x55\x4a\xef\x01\x60\xb8\xfc\x65\x3c\x0e\x00\x08\x0f\x4f\x78" |
| 602 | #pubk = "\x04\x14\xc1\xcf\x10\x99\x9d\x3a\x98\xf3\x71\xb8\xd8\x9b\x3b\x26\xb2\x9e\xe1\xbd\x99\xf3\xe0\x39\x3d\x34\x21\x6a\x6f\x49\x58\x7a\xb1\xdd\x8a\xba\x7a\x9d\x02\x99\x5f\xda\xa0\xb8\x62\x82\xae\xc2\xd0\xc6\x88\xc2\x26\x03\x97\x86\x65\x46\xbb\x20\xc9\xd1\x44\xb9\x84" |
| 603 | |
| 604 | if sbc_auth_inf == 0: |
| 605 | padbytes = '\0' * g_signature_size |
| 606 | signaturelist.append(padbytes) |
| 607 | else: |
| 608 | pem_key_format = mi_desc['pem_key_format'] |
| 609 | if(pem_key_format == 1): |
| 610 | '''PEM format''' |
| 611 | key_mode = 1 |
| 612 | elif(pem_key_format == 2): |
| 613 | '''DER format''' |
| 614 | key_mode = 2 |
| 615 | else: |
| 616 | '''String format''' |
| 617 | key_mode = 0 |
| 618 | |
| 619 | #ecdsa = cryptoSB.ECDSA() |
| 620 | #signature = ecdsa.sign(privk, pubk, boothash, sbc_auth_alg) |
| 621 | ''' 20180616 fix the sb_sign msg error : not boothash -> blh is right''' |
| 622 | if(ck_en == 0): |
| 623 | print("original format: no change key:") |
| 624 | signature = cryptoSB.sb_sign(privk, pubk, blh, sbc_auth_alg, sbc_auth_alg_hash, rsa_parse, sbc_rsa_pad_sel, key_mode) |
| 625 | else: |
| 626 | signature = cryptoSB.sb_sign(signckprivk, pubk, blh, sbc_auth_alg, sbc_auth_alg_hash, ck_rsa_parse, sbc_rsa_pad_sel, key_mode) |
| 627 | |
| 628 | #print("signature size = %d" %len(signature)) |
| 629 | signature_append = my_pad_to_align(signature, g_signature_size) |
| 630 | #cryptoSB.dump(signature_append) |
| 631 | signaturelist.append(signature_append) |
| 632 | |
| 633 | #check verify |
| 634 | #ret = ecdsa.verify(pubk, boothash, signature, sbc_auth_alg) |
| 635 | #print("ecdsa verify: %s" %ret) |
| 636 | |
| 637 | |
| 638 | #dump("".join(signaturelist)) |
| 639 | # append signature |
| 640 | pack += signaturelist |
| 641 | |
| 642 | # for easy view, please remove it while release final |
| 643 | '''align for (bl + imgl + sbc + auth + ck)''' |
| 644 | if(__Align_16_en == 1): |
| 645 | padnum = pad_to_align(16, len(''.join(pack))) |
| 646 | pack.append(padnum) |
| 647 | |
| 648 | # append ck field |
| 649 | ''' Skipped: no use on 2735 |
| 650 | pack += ck_region |
| 651 | |
| 652 | ck_field = ''.join(ck_region) |
| 653 | cryptoSB.dump(ck_field) |
| 654 | ckf = copy.copy(ck_field) |
| 655 | |
| 656 | ck_signature = cryptoSB.sb_sign(privk, pubk, ckf, sbc_auth_alg, sbc_auth_alg_hash, rsa_parse, sbc_rsa_pad_sel, key_mode) |
| 657 | #print("ck_signature size = %d" %len(ck_signature)) |
| 658 | ck_signature_append = my_pad_to_align(ck_signature, g_signature_size) |
| 659 | #cryptoSB.dump(ck_signature_append) |
| 660 | cksignaturelist.append(ck_signature_append) |
| 661 | |
| 662 | pack += cksignaturelist |
| 663 | ''' |
| 664 | # end append ck field |
| 665 | |
| 666 | # append image binary |
| 667 | for i in range(img_num): |
| 668 | offset = int(img_offset_table[i]) |
| 669 | pad_num = offset - len(''.join(pack)) |
| 670 | #print("offset = %d" %offset) |
| 671 | #print("pad_num = %d" %pad_num) |
| 672 | |
| 673 | padbytes = '\0' * pad_num |
| 674 | pack.append(padbytes) |
| 675 | pack += imagetmp[i] |
| 676 | |
| 677 | #print(len(''.join(pack))) |
| 678 | |
| 679 | # clear list |
| 680 | while len(signaturelist) > 0: |
| 681 | signaturelist.pop() |
| 682 | |
| 683 | |
| 684 | return ''.join(pack) |
| 685 | |
| 686 | '''support to_bytes to python 2.7''' |
| 687 | def my_to_bytes(n, length, endianess='big'): |
| 688 | h = '%x' % n |
| 689 | s = ('0'*(len(h) % 2) + h).zfill(length*2).decode('hex') |
| 690 | return s if endianess == 'big' else s[::-1] |
| 691 | |
| 692 | '''long to byte string''' |
| 693 | def my_binify(x): |
| 694 | h = hex(x)[2:].rstrip('L') |
| 695 | return binascii.unhexlify(h) |
| 696 | |
| 697 | def my_binify2(x): |
| 698 | if(hex(x)[0:2] == '0x'): |
| 699 | h = hex(x)[2:].rstrip('L') |
| 700 | else: |
| 701 | h = hex(x).rstrip('L') |
| 702 | |
| 703 | return binascii.unhexlify(h) |
| 704 | |
| 705 | def my_pad_to_align(x, align): |
| 706 | if(align == 0): |
| 707 | return x |
| 708 | else: |
| 709 | size = len(x) |
| 710 | #print("size 0x%x" %size) |
| 711 | pad_size = (align - size % align) % align |
| 712 | for i in range(0, pad_size, 1): |
| 713 | x += b'\x00' |
| 714 | |
| 715 | #cryptoSB.dump(x) |
| 716 | return x |
| 717 | |
| 718 | |
| 719 | def img_enc(mi_desc, key, align=None): |
| 720 | |
| 721 | images = mi_desc['images'] |
| 722 | img_num = len(images) |
| 723 | |
| 724 | img = images[0] |
| 725 | #load_addr = img['load_addr'] |
| 726 | #entrypoint = img['entrypoint'] |
| 727 | img_file = img['img_file'] |
| 728 | img_enc_alg = img['img_enc_alg'] |
| 729 | #print(img_enc_alg) |
| 730 | img_enc_inf = img['img_enc_inf'] |
| 731 | #print(img_enc_inf) |
| 732 | iv = img['img_iv'] |
| 733 | iv = my_binify(iv) |
| 734 | #print type(iv) |
| 735 | #print("img_enc dump:") |
| 736 | #cryptoSB.dump(iv) |
| 737 | |
| 738 | bin = open(img_file, 'rb').read() |
| 739 | #cryptoSB.dump(bin) |
| 740 | |
| 741 | #align |
| 742 | bin = my_pad_to_align(bin, 64) |
| 743 | |
| 744 | aes = cryptoSB.AESCipher(key, 16) |
| 745 | encmsg = aes.aes_encrypt(bin) |
| 746 | #print("result image enc:") |
| 747 | #cryptoSB.dump(encmsg) |
| 748 | |
| 749 | return encmsg |
| 750 | |
| 751 | |
| 752 | |
| 753 | |
| 754 | if __name__ == '__main__': |
| 755 | import os, sys, getopt |
| 756 | |
| 757 | |
| 758 | def print_usage(): |
| 759 | print ('usage:', os.path.basename(sys.argv[0]), "[options] <image config>.json\n", \ |
| 760 | 'options:\n', \ |
| 761 | '\t[-o | --output out.img]\n', \ |
| 762 | '\t[-h | --help]\n', \ |
| 763 | '\t[-i | --input]\n', \ |
| 764 | '\t[-k | --prikey hexkey e.g. 0x0102..]\n', \ |
| 765 | '\t[-s | --enckey hexkey e.g. 0x0102..]\n', \ |
| 766 | '\t[-p | --pemdir <pem path>\n', \ |
| 767 | '\t[-d | --imgdir <image path>\n') |
| 768 | |
| 769 | |
| 770 | def main(): |
| 771 | opts, args = getopt.getopt(sys.argv[1:], |
| 772 | 'ho:a:i:k:s:p:d:', |
| 773 | ['help', 'output=', 'align=', 'input=', |
| 774 | 'prikey=', 'enckey=', 'pemdir=', 'imgdir='] |
| 775 | ) |
| 776 | |
| 777 | out_name = None |
| 778 | align = 0 |
| 779 | infile_name = None |
| 780 | aeskey = None |
| 781 | pubkey = None |
| 782 | privk = None |
| 783 | pem_dir = "binfile" |
| 784 | img_dir = '' |
| 785 | |
| 786 | for o, a in opts: |
| 787 | if o in ('-h', '--help'): |
| 788 | print_usage() |
| 789 | sys.exit() |
| 790 | elif o in ('-o', '--output'): |
| 791 | out_name = a |
| 792 | elif o in ('-a', '--align'): |
| 793 | align = int(a) |
| 794 | elif o in ('-i', '--input'): |
| 795 | ## doesn't need currently |
| 796 | infile_name = a |
| 797 | elif o in ('-k', '--prikey'): |
| 798 | privkey = a |
| 799 | elif o in ('-s', '--enckey'): |
| 800 | aeskey = a |
| 801 | elif o in ('-p', '--pemdir'): |
| 802 | pem_dir = a |
| 803 | elif o in ('-d', '--imgdir'): |
| 804 | img_dir = a |
| 805 | else: |
| 806 | print_usage() |
| 807 | sys.exit(1) |
| 808 | |
| 809 | if len(args) >= 1: |
| 810 | mi_desc_fn = args[0] |
| 811 | else: |
| 812 | print_usage() |
| 813 | sys.exit(1) |
| 814 | |
| 815 | if not out_name: |
| 816 | fn, ext = os.path.splitext(mi_desc_fn) |
| 817 | out_name = fn + '.img' |
| 818 | |
| 819 | """ read json script """ |
| 820 | mi_desc = read_desc(mi_desc_fn) |
| 821 | |
| 822 | #mipack = pack_images(mi_desc, align) |
| 823 | |
| 824 | #print 'output: %s (%d bytes)' % (out_name, len(mipack)) |
| 825 | #open(out_name, 'wb').write(mipack) |
| 826 | |
| 827 | cmd_line_key = mi_desc['cmd_line_key'] |
| 828 | sign_priv_key = mi_desc['sign_priv_key'] |
| 829 | aes_enc_sym_key = mi_desc['aes_enc_sym_key'] |
| 830 | |
| 831 | """ Where is the key input from """ |
| 832 | |
| 833 | pem_key_format = mi_desc['pem_key_format'] |
| 834 | if(pem_key_format == 1): |
| 835 | sbc_auth_alg = mi_desc['sbc_auth_alg'] |
| 836 | if(sbc_auth_alg == 0): |
| 837 | key_path = pem_dir + "/ecdsa_p256_private.pem" |
| 838 | #print(key_path) |
| 839 | privk = open(key_path,"rb").read() |
| 840 | #privk = open("binfile/ecdsa_p256_private.pem","rb").read() |
| 841 | #pubk_pem = open("binfile/ecdsa_p256_public.pem","rb").read() |
| 842 | elif(sbc_auth_alg == 1): |
| 843 | privk = open("binfile/ecdsa_p384_private.pem","rb").read() |
| 844 | |
| 845 | key = cryptoSB.strip_key(aes_enc_sym_key) |
| 846 | |
| 847 | else: |
| 848 | if(cmd_line_key == 1): |
| 849 | key = cryptoSB.strip_key(aeskey) |
| 850 | privk = cryptoSB.strip_key(privkey) |
| 851 | #print("dump privkey:") |
| 852 | #cryptoSB.dump(privk) |
| 853 | elif(cmd_line_key == 0): |
| 854 | key = cryptoSB.strip_key(aes_enc_sym_key) |
| 855 | privk = cryptoSB.strip_key(sign_priv_key) |
| 856 | #print("dump privkey:") |
| 857 | #cryptoSB.dump(privk) |
| 858 | else: |
| 859 | prnit("ERROR: please check cmd_line_key json") |
| 860 | |
| 861 | |
| 862 | |
| 863 | #run hash |
| 864 | #hash = cryptoSB.HASH() |
| 865 | #imghash = hash.hash_sha256(enc_data) |
| 866 | #cryptoSB.dump(imghash) |
| 867 | |
| 868 | mipack = my_pack_images(mi_desc, privk, key, align, img_dir) |
| 869 | if mipack == None: |
| 870 | print("my_pack_images fail") |
| 871 | return |
| 872 | |
| 873 | #out_name = 'my_' + fn + '.img' |
| 874 | #out_name = fn + '.img' |
| 875 | print('output: %s (%d bytes)' % (out_name, len(mipack))) |
| 876 | open(out_name, 'wb').write(mipack) |
| 877 | |
| 878 | main() |
| 879 | |