12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- #!/usr/bin/env python3
- import argparse
- import re
- import struct
- import subprocess
- import zlib
- def main():
- parser = argparse.ArgumentParser()
- parser.add_argument('--input-file', type=str, required=True)
- parser.add_argument('--output-file', type=str, required=True)
- parser.add_argument('--model', type=str, required=True)
- parser.add_argument('--region', type=str, required=True)
- parser.add_argument('--version', type=str, required=True)
- parser.add_argument('--hw-id-list', type=str)
- parser.add_argument('--model-list', type=str)
- parser.add_argument('--encryption-block-size', type=str, required=True)
- parser.add_argument('--openssl-bin', type=str, required=True)
- parser.add_argument('--key', type=str, required=True)
- parser.add_argument('--iv', type=str, required=True)
- args = parser.parse_args()
- assert re.match(r'V[0-9]\.[0-9]\.[0-9]\.[0-9]',
- args.version), 'Version must start with Vx.x.x.x'
- encryption_block_size = int(args.encryption_block_size, 0)
- assert (encryption_block_size > 0 and encryption_block_size % 16 ==
- 0), 'Encryption block size must be a multiple of the AES block size (16)'
- hw_id_list = args.hw_id_list.split(';') if args.hw_id_list else []
- model_list = args.model_list.split(';') if args.model_list else []
- hw_info = ';'.join(hw_id_list + model_list)
- image = open(args.input_file, 'rb').read()
- image_enc = []
- for i in range(0, len(image), encryption_block_size):
- chunk = image[i:i + encryption_block_size]
- chunk += b'\x00' * ((-len(chunk)) % 16) # pad to AES block size (16)
- res = subprocess.run([
- args.openssl_bin,
- 'enc',
- '-aes-256-cbc',
- '-nosalt',
- '-nopad',
- '-K', args.key,
- '-iv', args.iv
- ],
- check=True, input=chunk, stdout=subprocess.PIPE)
- image_enc.append(res.stdout)
- image_enc = b''.join(image_enc)
- image_with_header = struct.pack(
- '>32s32s64s64sIBBB13s200s100s12sII',
- args.model.encode('ascii'),
- args.region.encode('ascii'),
- args.version.encode('ascii'),
- b'Thu Jan 1 00:00:00 1970', # static date for reproducibility
- 0, # product hw model
- 0, # model index
- len(hw_id_list),
- len(model_list),
- b'', # reserved
- hw_info.encode('ascii'),
- b'', # reserved
- b'encrpted_img',
- len(image_enc),
- encryption_block_size,
- ) + image_enc
- checksum = zlib.crc32(image_with_header, 0xffffffff) ^ 0xffffffff
- with open(args.output_file, 'wb') as outfile:
- outfile.write(image_with_header)
- outfile.write(struct.pack('>I', checksum))
- if __name__ == "__main__":
- main()
|