import sys from struct import pack as pk, unpack as up def u32(x): return x & 0xFFFFFFFF def tea_update_custom_mac(mac, v, k): v0, v1 = v[0], v[1] cur_sum = 0xC6EF3720 k0, k1, k2, k3 = k[0], k[1], k[2], k[3] mac[3] = u32(mac[3] - (u32((v0 << 4) + k1) ^ u32(mac[2] + cur_sum) ^ u32((v1 >> 5) + k2))) mac[2] = u32(mac[2] - (u32((v1 << 4) + k3) ^ u32(mac[3] + cur_sum) ^ u32((v0 >> 5) + k0))) mac[1] = u32(mac[1] - (u32((v0 << 4) + k2) ^ u32(mac[0] + cur_sum) ^ u32((v0 >> 5) + k3))) mac[0] = u32(mac[0] - (u32((v1 << 4) + k0) ^ u32(mac[1] + cur_sum) ^ u32((v1 >> 5) + k1))) def tea_decrypt(v, k): # Taken with love from Wikipedia v0, v1 = v[0], v[1] cur_sum = 0xC6EF3720 delta = 0x9E3779B9 k0, k1, k2, k3 = k[0], k[1], k[2], k[3] for i in xrange(0, 32): v1 = u32(v1 - (u32((v0 << 4) + k2) ^ u32(v0 + cur_sum) ^ u32((v0 >> 5) + k3))) v0 = u32(v0 - (u32((v1 << 4) + k0) ^ u32(v1 + cur_sum) ^ u32((v1 >> 5) + k1))) cur_sum = u32(cur_sum - delta) return [v0, v1] def tea_encrypt(v, k): # Taken with love from Wikipedia v0, v1 = v[0], v[1] cur_sum = 0 delta = 0x9E3779B9 k0, k1, k2, k3 = k[0], k[1], k[2], k[3] for i in xrange(0, 32): cur_sum = u32(cur_sum + delta) v0 = u32(v0 + (u32((v1 << 4) + k0) ^ u32(v1 + cur_sum) ^ u32((v1 >> 5) + k1))) v1 = u32(v1 + (u32((v0 << 4) + k2) ^ u32(v0 + cur_sum) ^ u32((v0 >> 5) + k3))) return [v0, v1] def get_key(offset): return [u32(0x73707048 + offset), u32(0xE8AD34FB + offset), u32(0xA4A8ACE6 + offset), u32(0x7B648B68 + offset)] def encrypt_firmware(data, do_print = True): # Parse header. # Checks from validate_firmware_header (sub_08000CA8) # Note that several of these checks are redundant, and header + 0xC is not used but is set.... assert len(data) >= 0x10 offset, size, version, _C = up('> 8, version & 0xFF, size) # Encrypt data. assert len(data) == 0x10 + size calc_mac = [0, 0, 0, 0] dec = data[0x10:] enc = '' for i in xrange(0, size, 8): cur_key = get_key(i) cur_dec = up('= 0x20 offset, size, version, _C = up('> 8, version & 0xFF, size) # Decrypt data. assert len(data) == 0x20 + size calc_mac = [0, 0, 0, 0] enc = data[0x20:] dec = '' for i in xrange(0, size, 8): cur_key = get_key(i) cur_enc = up('