scripts: fix installed-size calculation
[openwrt/staging/stintel.git] / scripts / netgear-encrypted-factory.py
1 #!/usr/bin/env python3
2
3 import argparse
4 import re
5 import struct
6 import subprocess
7 import zlib
8
9
10 def main():
11 parser = argparse.ArgumentParser()
12 parser.add_argument('--input-file', type=str, required=True)
13 parser.add_argument('--output-file', type=str, required=True)
14 parser.add_argument('--model', type=str, required=True)
15 parser.add_argument('--region', type=str, required=True)
16 parser.add_argument('--version', type=str, required=True)
17 parser.add_argument('--hw-id-list', type=str)
18 parser.add_argument('--model-list', type=str)
19 parser.add_argument('--encryption-block-size', type=str, required=True)
20 parser.add_argument('--openssl-bin', type=str, required=True)
21 parser.add_argument('--key', type=str, required=True)
22 parser.add_argument('--iv', type=str, required=True)
23 args = parser.parse_args()
24
25 assert re.match(r'V[0-9]\.[0-9]\.[0-9]\.[0-9]',
26 args.version), 'Version must start with Vx.x.x.x'
27 encryption_block_size = int(args.encryption_block_size, 0)
28 assert (encryption_block_size > 0 and encryption_block_size % 16 ==
29 0), 'Encryption block size must be a multiple of the AES block size (16)'
30
31 hw_id_list = args.hw_id_list.split(';') if args.hw_id_list else []
32 model_list = args.model_list.split(';') if args.model_list else []
33 hw_info = ';'.join(hw_id_list + model_list)
34
35 image = open(args.input_file, 'rb').read()
36 image_enc = []
37 for i in range(0, len(image), encryption_block_size):
38 chunk = image[i:i + encryption_block_size]
39 chunk += b'\x00' * ((-len(chunk)) % 16) # pad to AES block size (16)
40 res = subprocess.run([
41 args.openssl_bin,
42 'enc',
43 '-aes-256-cbc',
44 '-nosalt',
45 '-nopad',
46 '-K', args.key,
47 '-iv', args.iv
48 ],
49 check=True, input=chunk, stdout=subprocess.PIPE)
50 image_enc.append(res.stdout)
51 image_enc = b''.join(image_enc)
52
53 image_with_header = struct.pack(
54 '>32s32s64s64sIBBB13s200s100s12sII',
55 args.model.encode('ascii'),
56 args.region.encode('ascii'),
57 args.version.encode('ascii'),
58 b'Thu Jan 1 00:00:00 1970', # static date for reproducibility
59 0, # product hw model
60 0, # model index
61 len(hw_id_list),
62 len(model_list),
63 b'', # reserved
64 hw_info.encode('ascii'),
65 b'', # reserved
66 b'encrpted_img',
67 len(image_enc),
68 encryption_block_size,
69 ) + image_enc
70
71 checksum = zlib.crc32(image_with_header, 0xffffffff) ^ 0xffffffff
72
73 with open(args.output_file, 'wb') as outfile:
74 outfile.write(image_with_header)
75 outfile.write(struct.pack('>I', checksum))
76
77
78 if __name__ == "__main__":
79 main()