hacks/dump-imessages/iphone-dataprotection/python_scripts/keystore/effaceable.py

69 lines
2.2 KiB
Python

from construct import RepeatUntil
from construct.core import Struct, Union
from construct.macros import *
from crypto.aes import AESdecryptCBC
from crypto.aeswrap import AESUnwrap
from zipfile import crc32
import struct
Dkey = 0x446B6579
EMF = 0x454D4621
BAG1 = 0x42414731
DONE = 0x444f4e45 #locker sentinel
#**** = 0x2A2A2A2A #wildcard for erase
#MAGIC (kL) | LEN (2bytes) | TAG (4) | DATA (LEN)
Locker = Struct("Locker",
String("magic",2),
ULInt16("length"),
Union("tag",
ULInt32("int"),
String("tag",4))
,
String("data", lambda ctx: ctx["length"])
)
Lockers = RepeatUntil(lambda obj, ctx: obj.tag.int == DONE, Locker)
def xor_strings(s, key):
res = ""
for i in xrange(len(s)):
res += chr(ord(s[i]) ^ ord(key[i%len(key)]))
return res
def check_effaceable_header(plog):
z = xor_strings(plog[:16], plog[16:32])
if z[:4] != "ecaF":
return False
plog_generation = struct.unpack("<L", plog[0x38:0x3C])[0]
print "Effaceable generation" , plog_generation
plog_crc = crc32(plog[0x40:0x40 + 960], crc32(plog[0x20:0x3C], crc32(z))) & 0xffffffff
assert plog_crc == struct.unpack("<L", plog[0x3C:0x40])[0] , "Effaceable CRC"
print "Effaceable CRC OK"
return True
class EffaceableLockers(object):
def __init__(self, data):
self.lockers = {}
for l in Lockers.parse(data):
tag = l.tag.int & ~0x80000000
tag = struct.pack("<L", tag)[::-1]
self.lockers[tag] = l.data
def display(self):
print "Lockers : " + ", ".join(sorted(self.lockers.keys()))
def get(self, tag):
return self.lockers.get(tag)
def get_DKey(self, k835):
if self.lockers.has_key("Dkey"):
return AESUnwrap(k835, self.lockers["Dkey"])
def get_EMF(self, k89b):
if self.lockers.has_key("LwVM"):
lwvm = AESdecryptCBC(self.lockers["LwVM"], k89b)
return lwvm[-32:]
elif self.lockers.has_key("EMF!"):
return AESdecryptCBC(self.lockers["EMF!"][4:], k89b)