rjw | 1f88458 | 2022-01-06 17:20:42 +0800 | [diff] [blame^] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | import sys |
| 4 | import os |
| 5 | import argparse |
| 6 | import pp_tbl |
| 7 | |
| 8 | SS_SEED = ( |
| 9 | 0x576A, 0x05E8, 0x629D, 0x45A3, 0x649C, 0x4BF0, 0x2342, 0x272E, |
| 10 | 0x7358, 0x4FF3, 0x73EC, 0x5F70, 0x7A60, 0x1AD8, 0x3472, 0x3612, |
| 11 | 0x224F, 0x0454, 0x030E, 0x70A5, 0x7809, 0x2521, 0x484F, 0x5A2D, |
| 12 | 0x492A, 0x043D, 0x7F61, 0x3969, 0x517A, 0x3B42, 0x769D, 0x0647, |
| 13 | 0x7E2A, 0x1383, 0x49D9, 0x07B8, 0x2578, 0x4EEC, 0x4423, 0x352F, |
| 14 | 0x5B22, 0x72B9, 0x367B, 0x24B6, 0x7E8E, 0x2318, 0x6BD0, 0x5519, |
| 15 | 0x1783, 0x18A7, 0x7B6E, 0x7602, 0x4B7F, 0x3648, 0x2C53, 0x6B99, |
| 16 | 0x0C23, 0x67CF, 0x7E0E, 0x4D8C, 0x5079, 0x209D, 0x244A, 0x747B, |
| 17 | 0x350B, 0x0E4D, 0x7004, 0x6AC3, 0x7F3E, 0x21F5, 0x7A15, 0x2379, |
| 18 | 0x1517, 0x1ABA, 0x4E77, 0x15A1, 0x04FA, 0x2D61, 0x253A, 0x1302, |
| 19 | 0x1F63, 0x5AB3, 0x049A, 0x5AE8, 0x1CD7, 0x4A00, 0x30C8, 0x3247, |
| 20 | 0x729C, 0x5034, 0x2B0E, 0x57F2, 0x00E4, 0x575B, 0x6192, 0x38F8, |
| 21 | 0x2F6A, 0x0C14, 0x45FC, 0x41DF, 0x38DA, 0x7AE1, 0x7322, 0x62DF, |
| 22 | 0x5E39, 0x0E64, 0x6D85, 0x5951, 0x5937, 0x6281, 0x33A1, 0x6A32, |
| 23 | 0x3A5A, 0x2BAC, 0x743A, 0x5E74, 0x3B2E, 0x7EC7, 0x4FD2, 0x5D28, |
| 24 | 0x751F, 0x3EF8, 0x39B1, 0x4E49, 0x746B, 0x6EF6, 0x44BE, 0x6DB7) |
| 25 | |
| 26 | def fetch_seed(ran_type, seeds, idx): |
| 27 | if ran_type == "SS": |
| 28 | seed_page = seeds[idx % len(seeds)] |
| 29 | seed_page &= 0x7fff |
| 30 | key = seed_page |
| 31 | return (key, seed_page) |
| 32 | else: |
| 33 | pass |
| 34 | |
| 35 | def pn_gen(ran_type, src_len, key): |
| 36 | pn_buf = [] |
| 37 | for i in range(src_len): |
| 38 | pn_buf.append(0) |
| 39 | if ran_type == "SS": |
| 40 | for j in range(8): |
| 41 | if bool(key & 0x4000) != bool(key & 0x2000): |
| 42 | key <<= 1 |
| 43 | key &= 0x7ffe |
| 44 | key += 1 |
| 45 | pn_buf[i] += 1 << j |
| 46 | else: |
| 47 | key <<= 1 |
| 48 | key &= 0x7ffe |
| 49 | else: |
| 50 | pass |
| 51 | return (key, pn_buf) |
| 52 | |
| 53 | def randomizer(in_image, out_image, ran_type, sec_reseed, page_size, spare_size, sector_size, page_per_block, ppen, vendor): |
| 54 | # check file length # |
| 55 | if (os.path.getsize(in_image) % (page_size + spare_size)) != 0: |
| 56 | raise Exception("input image size is not page size aligned") |
| 57 | |
| 58 | page_number = os.path.getsize(in_image) / (page_size + spare_size) |
| 59 | sec_per_page = page_size / sector_size |
| 60 | spare_per_sec = spare_size / sec_per_page |
| 61 | |
| 62 | if ran_type == "SS": |
| 63 | seeds = SS_SEED |
| 64 | else: |
| 65 | raise Exception("not support %s randomizer" % ran_type) |
| 66 | if ppen == 1: |
| 67 | if vendor == 'TSB': |
| 68 | PP = pp_tbl.TSB_PP |
| 69 | else: |
| 70 | raise Exception("unsupport %s pp table " % vendor) |
| 71 | |
| 72 | f_in = open(in_image, "rb") |
| 73 | f_out = open(out_image, "wb") |
| 74 | |
| 75 | for i in range(page_number): |
| 76 | percent = float(i) / float(page_number) * 100 |
| 77 | sys.stdout.writelines("%.1f"%percent) |
| 78 | sys.stdout.writelines("%\r") |
| 79 | sys.stdout.flush(); |
| 80 | if ppen == 1: |
| 81 | seed_idx = PP[i % (page_per_block / 2)] |
| 82 | else: |
| 83 | seed_idx = i % page_per_block |
| 84 | (key, seed_page) = fetch_seed(ran_type, seeds, seed_idx) |
| 85 | for j in range(sec_per_page): |
| 86 | if sec_reseed: |
| 87 | key = seed_page |
| 88 | |
| 89 | (key, pn_buf) = pn_gen(ran_type, sector_size + spare_per_sec, key) |
| 90 | |
| 91 | in_buf = f_in.read(sector_size + spare_per_sec) |
| 92 | if not in_buf: |
| 93 | break |
| 94 | in_buf = bytearray(in_buf) |
| 95 | |
| 96 | for k in range(sector_size + spare_per_sec): |
| 97 | in_buf[k] ^= pn_buf[k] |
| 98 | |
| 99 | in_buf = str(in_buf) |
| 100 | f_out.write(in_buf) |
| 101 | |
| 102 | f_in.close() |
| 103 | f_out.close() |
| 104 | |
| 105 | def main(argv): |
| 106 | parser = argparse.ArgumentParser() |
| 107 | parser.add_argument('in_image', help = 'input image w/o random ') |
| 108 | parser.add_argument('out_image', help = 'output image w/ random ') |
| 109 | parser.add_argument('ran_type', default = 'SS', help = 'randomizer algorithm: SS or TSB') |
| 110 | parser.add_argument('sec_reseed', default = '1', help = 'whether reseed each sector') |
| 111 | parser.add_argument('page_size', help = 'page size') |
| 112 | parser.add_argument('spare_size', help = 'page spare size') |
| 113 | parser.add_argument('sector_size', help = 'sector size') |
| 114 | parser.add_argument('page_per_block', help = 'page per block number') |
| 115 | parser.add_argument('ppen', help = 'whether paired page is enabled') |
| 116 | parser.add_argument('vendor', help = 'vendor name') |
| 117 | args = parser.parse_args() |
| 118 | |
| 119 | randomizer(args.in_image, args.out_image, args.ran_type, int(args.sec_reseed), int(args.page_size), \ |
| 120 | int(args.spare_size), int(args.sector_size), int(args.page_per_block), int(args.ppen), args.vendor) |
| 121 | |
| 122 | if __name__ == "__main__": |
| 123 | sys.exit(main(sys.argv)) |