Beispiel #1
0
    def Decryption(self):
        dict = {}
        for type, data in tlvs(self.fbuf[KEYBAG_DATA_SIZE +
                                         KEYBAG_HEADER_SIZE:self.endofdata]):
            #if type == 'UUID':
            #print '%s : %s'%(type, uuid.UUID(bytes=data) )
            if type == 'CLAS':
                #print ' [-] %s : %s %d'%(type, get_class_name(int(hexlify(data), 16) ), int(hexlify(data), 16))
                dict['CLAS'] = int(hexlify(data), 16)
            elif type == 'WRAP':
                #print ' [-] %s : %s'%(type, get_wrap_name(int(hexlify(data), 16) ))
                dict['WRAP'] = int(hexlify(data), 16)
            elif type == 'KTYP':
                #print ' [-] %s : %s'%(type, get_key_type(int(hexlify(data), 16) ))
                dict['KTYP'] = int(hexlify(data), 16)
            elif type == 'WPKY':
                decryptedkey = ''

                if dict['WRAP'] == 1:
                    decryptedkey = AESdecryptCBC(data, self.devicekey)
                    #print ' [-] Decrypted Key : %s'%hexlify(decryptedkey)
                elif dict['WRAP'] == 3:
                    try:
                        unwrapped = AESUnwrap(self.passcodekey, data)
                    except ValueError:
                        print '[!] Invalid Password. Enter the valid user password'
                        sys.exit()
                    decryptedkey = AESdecryptCBC(unwrapped, self.devicekey)
                    #print ' [-] Decrypted Key : %s'%hexlify(decryptedkey)

                self.keyring[dict['CLAS']] = decryptedkey  # Key
def getEMFkeyFromCRPT(data, key89B):
    assert data.startswith("tprc")
    z = AESdecryptCBC(data[4:0x44], key89B)
    assert z.startswith("TPRC"), "wrong key89B"
    #last_byte = struct.unpack("<Q", z[4:4+8])[0]
    emf = z[16:16+32]
    return emf
Beispiel #3
0
    def read_file(self, filename, record):
        # read backup file
        try:
            f = file(self.backup_path + '/' + filename, 'rb')
            file_data = f.read()
            f.close()
        except (IOError):
            warn("File %s (%s) has not been found" % (filename, record.path))
            return

        if record.encryption_key is not None and self.keybag:  # file is encrypted!
            key = self.keybag.unwrapKeyForClass(record.protection_class,
                                                record.encryption_key[4:])
            if not key:
                warn("Cannot unwrap key")
                return
            file_data = AESdecryptCBC(file_data, key)
            padding = file_data[record.size:]
            if len(padding) > 16 or padding != chr(
                    len(padding)) * len(padding):
                warn("Incorrect padding for file %s %d %d" %
                     (record.path, len(file_data), record.size))
                c = file_data[-1]
                i = ord(c)
                if i < 17 and file_data.endswith(c * i):
                    warn("But good padding of %d anyway" % i)
                    file_data = file_data[:-i]

                return file_data
            file_data = file_data[:record.size]
        return file_data
def getEMFkeyFromCRPT(data, key89B):
    assert data.startswith("tprc")
    z = AESdecryptCBC(data[4:0x44], key89B)
    assert z.startswith("TPRC"), "wrong key89B"
    #last_byte = struct.unpack("<Q", z[4:4+8])[0]
    emf = z[16:16+32]
    return emf
Beispiel #5
0
def decrypt_blob(blob, auth_key):
    len = struct.unpack(">H", blob[0:2])[0]
    if len != 66:
        print "blob len != 66"
    magic = struct.unpack(">H", blob[2:4])[0]
    if magic != 0x0100:
        print "magic != 0x0100"
    iv = blob[4:20]

    blob_key = AESdecryptCBC(blob[20:68], auth_key, iv)[:32]

    return AESdecryptCBC(blob[68:], blob_key, iv, padding=True)
Beispiel #6
0
    def Decryption(self):

        if self.keybag['version'] >= 5:
            wrap_iv_digest = sha256(struct.pack('<ll', 0, 5))
            wrap_iv_digest.update(unhexlify(self.keybag['salt']))
            key_store_wrap_iv = wrap_iv_digest.digest()[:16]

        dict = {}
        for type, data in tlvs(self.fbuf[KEYBAG_DATA_SIZE +
                                         KEYBAG_HEADER_SIZE:self.endofdata]):
            #if type == 'UUID':
            #print '%s : %s'%(type, uuid.UUID(bytes=data) )
            if type == 'CLAS':
                print ' [-] %s : %s %d' % (
                    type, get_class_name(int(hexlify(data),
                                             16)), int(hexlify(data), 16))
                dict['CLAS'] = int(hexlify(data), 16)
            elif type == 'WRAP':
                print ' [-] %s : %s' % (type,
                                        get_wrap_name(int(hexlify(data), 16)))
                dict['WRAP'] = int(hexlify(data), 16)
            elif type == 'KTYP':
                print ' [-] %s : %s' % (type,
                                        get_key_type(int(hexlify(data), 16)))
                dict['KTYP'] = int(hexlify(data), 16)
            elif type == 'WPKY':
                decryptedkey = ''

                if dict['WRAP'] == 1:
                    if self.keybag['version'] >= 5:
                        decryptedkey = AESdecryptCBC(data, self.devicekey,
                                                     key_store_wrap_iv)
                    else:
                        decryptedkey = AESdecryptCBC(data, self.devicekey)
                    print ' [-] Decrypted Key : %s' % hexlify(decryptedkey)
                elif dict['WRAP'] == 3:
                    if self.keybag['version'] >= 5:
                        data = AESdecryptCBC(data[:32], self.devicekey,
                                             key_store_wrap_iv) + data[32:40]

                    try:
                        unwrapped = AESUnwrap(self.passcodekey, data)
                    except ValueError:
                        print '[!] Invalid Password. Enter the valid user password'
                        sys.exit()

                    if self.keybag['version'] >= 5:
                        decryptedkey = unwrapped
                    else:
                        decryptedkey = AESdecryptCBC(unwrapped, self.devicekey)
                    print ' [-] Decrypted Key : %s' % hexlify(decryptedkey)

                self.keyring[dict['CLAS']] = decryptedkey  # Key
 def decryptFileBlock2(self, ciphertext, filekey, lbn, decrypt_offset):
     if not self.encrypted:
         return ciphertext
     if not self.image.isIOS5():
         return AESdecryptCBC(ciphertext, filekey, self.volume.ivForLBA(lbn, add=False))
     clear = ""
     ivkey = hashlib.sha1(filekey).digest()[:16]
     for i in xrange(len(ciphertext)/0x1000):
         iv =  self.volume.ivForLBA(decrypt_offset, False)
         iv = AESencryptCBC(iv, ivkey)
         clear += AESdecryptCBC(ciphertext[i*0x1000:(i+1)*0x1000], filekey, iv)
         decrypt_offset += 0x1000
     return clear
Beispiel #8
0
 def processBlock(self, block, lba):
     iv = self.volume.ivForLBA(lba)
     ciphertext = AESencryptCBC(block, self.volume.emfkey, iv)
     if not self.ivkey:
         clear = AESdecryptCBC(ciphertext, self.filekey, iv)
     else:
         clear = ""
         for i in xrange(len(block) / 0x1000):
             iv = self.volume.ivForLBA(self.decrypt_offset, False)
             iv = AESencryptCBC(iv, self.ivkey)
             clear += AESdecryptCBC(ciphertext[i * 0x1000:(i + 1) * 0x1000],
                                    self.filekey, iv)
             self.decrypt_offset += 0x1000
     return clear
Beispiel #9
0
 def createWithSystemkbfile(filename, bag1key, deviceKey=None):
     if filename.startswith("bplist"): #HAX
         mkb = BPlistReader.plistWithString(filename)
     else:
         mkb = BPlistReader.plistWithFile(filename)
     try:
         decryptedPlist  = AESdecryptCBC(mkb["_MKBPAYLOAD"].data, bag1key, mkb["_MKBIV"].data, padding=True)
     except:
         print "FAIL: AESdecryptCBC _MKBPAYLOAD => wrong BAG1 key ?"
         return None
     if not decryptedPlist.startswith("bplist"):
         print "FAIL: decrypted _MKBPAYLOAD is not bplist"
         return None
     decryptedPlist = BPlistReader.plistWithString(decryptedPlist)
     blob = decryptedPlist["KeyBagKeys"].data
     return Keybag.createWithDataSignBlob(blob, deviceKey)
Beispiel #10
0
    def readLPN(self, lpn, key=None):
        z = self.conn.execute(
            "SELECT ce,block,page,weaveSeq from lpn_to_phys WHERE lpn=? ORDER BY weaveSeq DESC LIMIT 1",
            (lpn, )).fetchone()
        if z:
            #weave,ce,block,page = a[-1]
            ce, block, page, weaveSeq = z
        else:
            print "lpn %d => blank" % lpn
            return self.blankPage
        #print "lpn=%d weaveSeq=%d" % (lpn, weaveSeq)

        s, d = self.nand.readBlockPage(ce,
                                       block,
                                       page,
                                       None,
                                       lpn,
                                       spareType=self.spareType)

        for i in xrange(len(s)):
            if s[i].lpn == lpn:
                o = i * self.logicalPageSize
                data = d[o:o + self.logicalPageSize]
                if key:
                    data = AESdecryptCBC(data, key, ivForPage(lpn))
                return data
        raise Exception("readLPN %d failed" % lpn)
Beispiel #11
0
    def decrypt_protected_file(self, path, filekey, decrypted_size=0):
        ivkey = hashlib.sha1(filekey).digest()[:16]
        hash = hashlib.sha1()
        sz = os.path.getsize(path)

        oldpath = path + ".encrypted"
        try:
            os.rename(path, oldpath)
        except:
            pass

        with open(oldpath, "rb") as old_file:
            with open(path, "wb") as new_file:
                n = sz / 0x1000
                if decrypted_size:
                    n += 1

                for block in xrange(n):
                    iv = AESencryptCBC(self.computeIV(block * 0x1000), ivkey)
                    old_data = old_file.read(0x1000)
                    hash.update(old_data)
                    new_file.write(AESdecryptCBC(old_data, filekey, iv))

                if decrypted_size == 0:  #old iOS 5 format
                    trailer = old_file.read(0x1C)
                    decrypted_size = struct.unpack(">Q", trailer[:8])[0]
                    assert hash.digest() == trailer[8:]

                new_file.truncate(decrypted_size)

                os.remove(oldpath)  # Delete the encrypted file
Beispiel #12
0
 def decryptProtectedFile(self, path, filekey, DecryptedSize=0):
     ivkey = hashlib.sha1(filekey).digest()[:16]
     h = hashlib.sha1()
     sz = os.path.getsize(path)
     #iOS 5 trailer = uint64 sz + sha1 of encrypted file
     #assert (sz % 0x1000) == 0x1C
     oldpath = path + ".encrypted"
     try:
         os.rename(path, oldpath)
     except:
         pass
     f1 = open(oldpath, "rb")
     f2 = open(path, "wb")
     n = (sz / 0x1000)
     if DecryptedSize:
         n += 1
     for block in xrange(n):
         iv = AESencryptCBC(self.computeIV(block * 0x1000), ivkey)
         data = f1.read(0x1000)
         h.update(data)
         f2.write(AESdecryptCBC(data, filekey, iv))
     if DecryptedSize == 0:  #old iOS 5 format
         trailer = f1.read(0x1C)
         DecryptedSize = struct.unpack(">Q", trailer[:8])[0]
         assert h.digest() == trailer[8:]
     f1.close()
     f2.truncate(DecryptedSize)
     f2.close()
Beispiel #13
0
    def decrypt_blob(self, blob):
        if blob == None:
            return ""

        if len(blob) < 48:
            print "keychain blob length must be >= 48"
            return

        version, clas = struct.unpack("<LL", blob[0:8])
        self.clas = clas
        if version == 0:
            wrappedkey = blob[8:8 + 40]
            encrypted_data = blob[48:]
        elif version == 2:
            l = struct.unpack("<L", blob[8:12])[0]
            wrappedkey = blob[12:12 + l]
            encrypted_data = blob[12 + l:-16]
        else:
            raise Exception("unknown keychain verson ", version)
            return

        unwrappedkey = self.keybag.unwrapKeyForClass(clas, wrappedkey, False)
        if not unwrappedkey:
            return

        if version == 0:
            return AESdecryptCBC(encrypted_data, unwrappedkey, padding=True)
        elif version == 2:
            binaryplist = gcm_decrypt(unwrappedkey, "", encrypted_data, "",
                                      blob[-16:])
            return BPlistReader(binaryplist).parse()
Beispiel #14
0
    def decrypt_blob(self, blob):
        if blob == None:
            return ""

        if len(blob) < 48:
            print "keychain blob length must be >= 48"
            return

        version, clas = struct.unpack("<LL", blob[0:8])

        if version == 0:
            wrappedkey = blob[8:8 + 40]
            encrypted_data = blob[48:]
        elif version == 2:
            wrappedkey = blob[12:12 + 40]
            encrypted_data = blob[52:-16]
        else:
            raise Exception("unknown keychain verson ", version)
            return

        unwrappedkey = self.keybag.unwrapKeyForClass(clas, wrappedkey)
        if not unwrappedkey:
            print "keychain unwrap fail for item with class=%d (%s)" % (
                clas, KSECATTRACCESSIBLE.get(clas))
            return

        if version == 0:
            return AESdecryptCBC(encrypted_data, unwrappedkey, padding=True)
        elif version == 2:
            binaryplist = gcm_decrypt(unwrappedkey, "", encrypted_data, "",
                                      blob[-16:])
            return BPlistReader(binaryplist).parse()
 def createWithSystemkbfile(filename, wipeablekey, deviceKey=None):
     mkb = BPlistReader.plistWithFile(filename)
     decryptedPlist = AESdecryptCBC(mkb["_MKBPAYLOAD"],
                                    wipeablekey,
                                    mkb["_MKBIV"],
                                    padding=True)
     decryptedPlist = BPlistReader.plistWithString(decryptedPlist)
     blob = decryptedPlist["KeyBagKeys"]
     return Keybag.createWithDataSignBlob(blob, deviceKey)
 def unlockAlwaysAccessible(self):
     for classkey in self.classKeys.values():
         k = classkey["WPKY"]
         if classkey["WRAP"] == WRAP_DEVICE:
             if not self.deviceKey:
                 continue
             k = AESdecryptCBC(k, self.deviceKey)
             classkey["KEY"] = k
     return True
def carveEMFemptySpace(volume, file_keys, outdir):
    for lba, block in volume.unallocatedBlocks():
        iv = volume.ivForLBA(lba)
        for filekey in file_keys:
            ciphertext = AESencryptCBC(block, volume.emfkey, iv)
            clear = AESdecryptCBC(ciphertext, filekey, iv)
            if isDecryptedCorrectly(clear):
                print "Decrypted stuff at lba %x" % lba
                open(outdir + "/%x.bin" % lba, "wb").write(clear)
 def createWithSystemkbfile(filename, bag1key, deviceKey=None):
     if filename.startswith("bplist"):  #HAX
         mkb = BPlistReader.plistWithString(filename)
     else:
         mkb = BPlistReader.plistWithFile(filename)
     try:
         decryptedPlist = AESdecryptCBC(mkb["_MKBPAYLOAD"].data,
                                        bag1key,
                                        mkb["_MKBIV"].data,
                                        padding=True)
     except:
         print "FAIL: AESdecryptCBC _MKBPAYLOAD => wrong BAG1 key ?"
         return None
     if not decryptedPlist.startswith("bplist"):
         print "FAIL: decrypted _MKBPAYLOAD is not bplist"
         return None
     decryptedPlist = BPlistReader.plistWithString(decryptedPlist)
     blob = decryptedPlist["KeyBagKeys"].data
     return Keybag.createWithDataSignBlob(blob, deviceKey)
Beispiel #19
0
 def createWithSystemkbfile(filename, bag1key, deviceKey=None):
     if filename.startswith("bplist"): #HAX
         mkb = BPlistReader.plistWithString(filename)
     else:
         mkb = BPlistReader.plistWithFile(filename)
     try:
         decryptedPlist  = AESdecryptCBC(mkb["_MKBPAYLOAD"].data, bag1key, mkb["_MKBIV"].data, padding=True)
     except:
         print "FAIL: AESdecryptCBC _MKBPAYLOAD => wrong BAG1 key ?"
         return None
     if not decryptedPlist.startswith("bplist"):
         print "FAIL: decrypted _MKBPAYLOAD is not bplist"
         return None
     decryptedPlist = BPlistReader.plistWithString(decryptedPlist)
     blob = decryptedPlist["KeyBagKeys"].data
     kb = Keybag.createWithDataSignBlob(blob, deviceKey)
     if decryptedPlist.has_key("OpaqueStuff"):
         OpaqueStuff = BPlistReader.plistWithString(decryptedPlist["OpaqueStuff"].data)
         kb.passcodeComplexity = OpaqueStuff.get("keyboardType")
     return kb
    def decrypt_blob(self, blob):
        if blob == None:
            return ""

        if len(blob) < 48:
            print "keychain blob length must be >= 48"
            return

        version, clas = struct.unpack("<LL", blob[0:8])
        clas &= 0xF
        self.clas = clas
        if version == 0:
            wrappedkey = blob[8:8 + 40]
            encrypted_data = blob[48:]
        elif version == 2:
            l = struct.unpack("<L", blob[8:12])[0]
            wrappedkey = blob[12:12 + l]
            encrypted_data = blob[12 + l:-16]
        elif version == 3:
            l = struct.unpack("<L", blob[8:12])[0]
            wrappedkey = blob[12:12 + l]
            encrypted_data = blob[12 + l:-16]
        else:
            raise Exception("unknown keychain verson ", version)
            return

        unwrappedkey = self.keybag.unwrapKeyForClass(clas, wrappedkey, False)
        if not unwrappedkey:
            return

        if version == 0:
            return AESdecryptCBC(encrypted_data, unwrappedkey, padding=True)
        elif version == 2:
            binaryplist = gcm_decrypt(unwrappedkey, "", encrypted_data, "",
                                      blob[-16:])
            return BPlistReader(binaryplist).parse()
        elif version == 3:
            der = gcm_decrypt(unwrappedkey, "", encrypted_data, "", blob[-16:])
            stuff, tail = der_decode(der)
            rval = {}

            try:
                index = 0
                while True:
                    k = stuff.getComponentByPosition(
                        index).getComponentByPosition(0)
                    v = stuff.getComponentByPosition(
                        index).getComponentByPosition(1)
                    rval[str(k)] = str(v)
                    index += 1
            except:
                pass

            return rval
    def decrypt_blob(self, blob):
        if blob == None:
            return ""

        if len(blob) < 48:
            print "keychain blob length must be >= 48"
            return

        version, clas = struct.unpack("<LL", blob[0:8])
        clas &= 0xF
        self.clas = clas
        if version == 0:
            wrappedkey = blob[8:8 + 40]
            encrypted_data = blob[48:]
        elif version == 2:
            l = struct.unpack("<L", blob[8:12])[0]
            wrappedkey = blob[12:12 + l]
            encrypted_data = blob[12 + l:-16]
        elif version == 3:
            l = struct.unpack("<L", blob[8:12])[0]
            wrappedkey = blob[12:12 + l]
            encrypted_data = blob[12 + l:-16]
        else:
            raise Exception("unknown keychain verson ", version)
            return

        unwrappedkey = self.keybag.unwrapKeyForClass(clas, wrappedkey, False)
        if not unwrappedkey:
            return

        if version == 0:
            return AESdecryptCBC(encrypted_data, unwrappedkey, padding=True)
        elif version == 2:
            binaryplist = gcm_decrypt(unwrappedkey, "", encrypted_data, "",
                                      blob[-16:])
            return BPlistReader(binaryplist).parse()
        elif version == 3:
            der = gcm_decrypt(unwrappedkey, "", encrypted_data, "", blob[-16:])
            stuff = der_decode(der)[0]
            rval = {}
            for k, v in stuff:
                k = str(k)
                # NB - this is binary and may not be valid UTF8 data
                v = str(v)
                rval[k] = v
            return rval
    def decrypt_data(self, data):
        if data == None:
            return ""
        data = str(data)

        if not self.key835:
            print "Key 835 not availaible"
            return ""

        data = AESdecryptCBC(data[16:], self.key835, data[:16], padding=True)

        #data_column = iv + AES128_K835(iv, data + sha1(data))
        if hashlib.sha1(data[:-20]).digest() != data[-20:]:
            print "data field hash mismatch : bad key ?"
            return "ERROR decrypting data : bad key ?"

        return data[:-20]
    def decryptData(self, key=None, iv=None):
        if not self.sections.has_key("KBAG"):
            return self.getRawData()

        if not key or not iv:
            if not self.decryptKBAG():
                return
            key = self.key
            iv = self.iv

        data = AESdecryptCBC(self.sections["DATA"], key, iv)
        x = self.isValidDecryptedData(data)
        if not x:
            print >> sys.stderr, "%s : Decrypted data seems invalid" % self.shortname
            print >> sys.stderr, data[:50].encode("hex")
            return False
        print "%s : decrypted OK (%s)" % (self.shortname, x)
        return data[:self.datalen]
Beispiel #24
0
    def unlockWithPasscodeKey(self, passcodekey):
        if self.type != BACKUP_KEYBAG:
            if not self.deviceKey:
                print "ERROR, need device key to unlock keybag"
                return False

        for classkey in self.classKeys.values():
            k = classkey["WPKY"]
            if classkey["WRAP"] & WRAP_PASSCODE:
                k = AESUnwrap(passcodekey, classkey["WPKY"])
                if not k:
                    return False
            if classkey["WRAP"] & WRAP_DEVICE:
                if not self.deviceKey:
                    continue
                k = AESdecryptCBC(k, self.deviceKey)
            classkey["KEY"] = k
        self.unlocked = True
        return True
Beispiel #25
0
    def readPage1(self, addr, key, lpn):
        weave, ce, block, page = addr
        #ce, block, page = addr
        s, d = self.nand.readBlockPage(ce,
                                       block,
                                       page,
                                       None,
                                       lpn,
                                       spareType=self.spareType)

        for i in xrange(len(s)):
            if s[i].lpn == lpn:
                o = i * self.logicalPageSize
                data = d[o:o + self.logicalPageSize]
                if key:
                    data = AESdecryptCBC(data, key, ivForPage(lpn))
                    return data
                return data
        raise Exception("FAIL")
    def change_key835(self, newkey):
        tables = {
            "genp": "SELECT rowid, data FROM genp",
            "inet": "SELECT rowid, data FROM inet",
            "cert": "SELECT rowid, data FROM cert",
            "keys": "SELECT rowid, data FROM keys"
        }

        for t in tables.keys():
            for row in self.conn.execute(tables[t]):
                rowid = row["rowid"]
                data = str(row["data"])
                iv = data[:16]
                data = AESdecryptCBC(data[16:], self.key835, iv)
                data = AESencryptCBC(data, newkey, iv)
                data = iv + data
                data = buffer(data)
                self.conn.execute("UPDATE %s SET data=? WHERE rowid=?" % t,
                                  (data, rowid))
        self.conn.commit()
Beispiel #27
0
def decrypt_backup3(backupfolder, outputfolder, passphrase):
    auth_key = None
    manifest = readPlist(backupfolder + "/Manifest.plist")

    if manifest["IsEncrypted"]:
        manifest_data = manifest["Data"].data

        authdata = manifest["AuthData"].data

        pkbdf_salt = authdata[:8]
        iv = authdata[8:24]
        key = PBKDF2(passphrase, pkbdf_salt, iterations=2000).read(32)

        data = AESdecryptCBC(authdata[24:], key, iv)
        auth_key = data[:32]

        if hashlib.sha1(auth_key).digest() != data[32:52]:
            print "wrong auth key (hash mismatch) => wrong passphrase"
            return

        print "Passphrase seems OK"

    for mdinfo_name in glob.glob(backupfolder + "/*.mdinfo"):

        mddata_name = mdinfo_name[:-7] + ".mddata"
        mdinfo = readPlist(mdinfo_name)
        metadata = mdinfo["Metadata"].data
        if mdinfo["IsEncrypted"]:
            metadata = decrypt_blob(metadata, auth_key)
        metadata = BPlistReader.plistWithString(metadata)

        print metadata["Path"]

        filedata = read_file(mddata_name)
        if mdinfo["IsEncrypted"]:
            filedata = decrypt_blob(filedata, auth_key)

        filename = re.sub(r'[:|*<>?"]', "_", metadata["Path"])
        makedirs(outputfolder + "/" + os.path.dirname(filename))
        write_file(outputfolder + "/" + filename, filedata)
 def decryptPage(self, data, key, pageNum):
     return AESdecryptCBC(data, key, ivForPage(pageNum))
def decryptPseudoGID(data):
    pseudogid = "5F650295E1FFFC97CE77ABD49DD955B3".decode("hex")
    return AESdecryptCBC(data, pseudogid, padding=False)
    def sigcheck(self, k89A=None):
        if not self.sections.has_key("SHSH"):
            print "[x] FAIL sigcheck %s : no SHSH section" % self.shortname
            return False

        if not self.leaf_cert:
            #print "Extracting certificates"
            self.extractCertificates()
        cert = self.leaf_cert
        #print "Leaf cert subject: %s" % cert.get_subject()
        certChainOk = False
        while True:
            issuer = cert.get_issuer().as_text()
            #print "issuer: %s" % issuer
            if not self.certs.has_key(issuer):
                if not Img3.rootCert:
                    print "Cert chain stops at %s" % issuer
                    certChainOk = False
                    break
                #print "Verifying cert.",
                certChainOk = cert.verify(Img3.rootCert.get_pubkey())
                break
            issuer = self.certs[issuer]
            if not cert.verify(issuer.get_pubkey()):
                print "%s is not signed by %s (verify fail)" % (
                    cert.get_subject().as_text(),
                    issuer.get_subject().as_text())
                return False
            cert = issuer
        shsh = self.sections["SHSH"]
        print "Got SHSH"

        try:
            sig = self.leaf_cert.get_pubkey().get_rsa().public_decrypt(
                shsh, M2Crypto.RSA.pkcs1_padding)
        except:
            if k89A == None:
                print "SHSH RSA decrypt FAIL, IMG3 must be personalized (SHSH encrypted with k89A)"
                return False
            try:
                shsh = AESdecryptCBC(shsh, k89A)
                sig = self.leaf_cert.get_pubkey().get_rsa().public_decrypt(
                    shsh, M2Crypto.RSA.pkcs1_padding)
            except:
                raise
                return False

        #DigestInfo SHA1 http://www.ietf.org/rfc/rfc3447.txt
        sha1_digestInfo = "3021300906052b0e03021a05000414".decode("hex")
        if sig[:len(sha1_digestInfo)] == sha1_digestInfo:
            pass  #print "DigestInfo SHA1 OK"

        self.sig = sig = sig[len(sha1_digestInfo):]

        ok = sig == self.fileHash.digest()

        if ok:
            print "%s : signature check OK (%s)" % (self.shortname,
                                                    self.leaf_name)
        else:
            print "Signature check for %s failed" % self.shortname
            print "Decrypted SHA1 " + sig.encode("hex")
            print "Sigcheck area SHA1 " + self.fileHash.hexdigest()
        return ok
Beispiel #31
0
 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)
Beispiel #32
0
 def readBlock(self, blockNum):
     os.lseek(self.fd, self.offset + self.blockSize * blockNum, os.SEEK_SET)
     data = os.read(self.fd, self.blockSize)
     if self.encrypted:
         data = AESdecryptCBC(data, self.key, self.getIVforBlock(blockNum))
     return data