2023-05-13 21:25:27 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
2023-05-16 16:32:14 +00:00
|
|
|
from binascii import crc_hqx as crc16
|
2023-05-16 11:33:04 +00:00
|
|
|
from itertools import cycle
|
2023-05-13 21:25:27 +00:00
|
|
|
import os
|
|
|
|
from pathlib import Path
|
2023-05-14 08:11:27 +00:00
|
|
|
from sys import argv
|
2023-05-16 11:33:04 +00:00
|
|
|
from sys import stderr
|
2023-05-13 21:25:27 +00:00
|
|
|
|
2023-05-16 11:33:04 +00:00
|
|
|
# Structure of pre-encoded payload
|
|
|
|
# 8196 | 16 | ... | 2 |
|
|
|
|
# data | version | data | crc |
|
|
|
|
|
|
|
|
KEY = Path('./key.bin').read_bytes()
|
|
|
|
|
2023-05-16 16:32:14 +00:00
|
|
|
V_START = 8192
|
|
|
|
V_END = V_START + 16
|
2023-05-16 11:33:04 +00:00
|
|
|
CRC_LEN = 2
|
|
|
|
|
|
|
|
def eprint(*args, **kwargs):
|
|
|
|
print(*args, **kwargs, file=stderr)
|
|
|
|
|
|
|
|
|
|
|
|
def xor(var):
|
|
|
|
return bytes(a ^ b for a, b in zip(var, cycle(KEY)))
|
|
|
|
|
|
|
|
|
2023-05-16 18:28:00 +00:00
|
|
|
def make_16byte_version(version):
|
|
|
|
return bytes([ord(c) for c in version] + [0] * (16 - len(version)))
|
|
|
|
|
|
|
|
|
2023-05-16 11:33:04 +00:00
|
|
|
def decrypt(data):
|
|
|
|
decrypted = xor(data)
|
2023-05-16 16:32:14 +00:00
|
|
|
eprint('version:', decrypted[V_START:V_END].decode())
|
2023-05-16 18:28:00 +00:00
|
|
|
return decrypted[:V_START] + decrypted[V_END:-CRC_LEN]
|
2023-05-16 11:33:04 +00:00
|
|
|
|
|
|
|
|
2023-05-16 18:28:00 +00:00
|
|
|
def encrypt(data, version='2.01.26'):
|
|
|
|
v = make_16byte_version(version)
|
|
|
|
encrypted = xor(data[:V_START] + v + data[V_START:])
|
2023-05-16 16:32:14 +00:00
|
|
|
checksum = crc16(encrypted, 0).to_bytes(2, 'little')
|
2023-05-16 11:33:04 +00:00
|
|
|
return encrypted + checksum
|
2023-05-13 21:25:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
def usage(info = None):
|
|
|
|
if info:
|
2023-05-14 07:18:12 +00:00
|
|
|
eprint(info)
|
|
|
|
eprint(f'Usage: {argv[0]} <e|d> filename.bin > raw.bin')
|
|
|
|
eprint(f' Example decode: {argv[0]} d k5_26_encrypted.bin > k5_26_raw.bin')
|
|
|
|
eprint(f' Example encode: {argv[0]} e k5_26_raw.bin > k5_26_encrypted.bin')
|
2023-05-13 21:25:27 +00:00
|
|
|
exit(128)
|
|
|
|
|
2023-05-14 07:18:12 +00:00
|
|
|
|
2023-05-13 21:25:27 +00:00
|
|
|
def main():
|
2023-05-16 11:33:04 +00:00
|
|
|
if len(argv) == 3:
|
|
|
|
mode = argv[1]
|
|
|
|
file_bytes = Path(argv[2]).read_bytes()
|
|
|
|
|
|
|
|
if mode == 'd':
|
|
|
|
os.write(1, decrypt(file_bytes))
|
|
|
|
eprint('Success!')
|
|
|
|
return
|
|
|
|
|
|
|
|
if mode == 'e':
|
|
|
|
os.write(1, encrypt(file_bytes))
|
|
|
|
eprint('Success!')
|
|
|
|
return
|
2023-05-13 21:25:27 +00:00
|
|
|
|
|
|
|
usage()
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|