コード例 #1
0
    def setMasterKeyRev(self, newMasterKeyRev):
        if not Titles.contains(self.titleId):
            raise IOError('No title key found in database! ' + self.titleId)

        ticket = self.ticket()
        masterKeyRev = ticket.getMasterKeyRevision()
        titleKey = ticket.getTitleKeyBlock()
        newTitleKey = Keys.changeTitleKeyMasterKey(
            titleKey.to_bytes(16, byteorder='big'),
            Keys.getMasterKeyIndex(masterKeyRev),
            Keys.getMasterKeyIndex(newMasterKeyRev))
        rightsId = ticket.getRightsId()

        if rightsId != 0:
            raise IOError('please remove titlerights first')

        if (newMasterKeyRev == None
                and rightsId == 0) or masterKeyRev == newMasterKeyRev:
            Print.info('Nothing to do')
            return

        Print.info('rightsId =\t' + hex(rightsId))
        Print.info('titleKey =\t' +
                   str(hx(titleKey.to_bytes(16, byteorder='big'))))
        Print.info('newTitleKey =\t' + str(hx(newTitleKey)))
        Print.info('masterKeyRev =\t' + hex(masterKeyRev))

        for nca in self:
            if type(nca) == Nca:
                if nca.header.getCryptoType2() != masterKeyRev:
                    pass
                    raise IOError('Mismatched masterKeyRevs!')

        ticket.setMasterKeyRevision(newMasterKeyRev)
        ticket.setRightsId((ticket.getRightsId()
                            & 0xFFFFFFFFFFFFFFFF0000000000000000) +
                           newMasterKeyRev)
        ticket.setTitleKeyBlock(int.from_bytes(newTitleKey, 'big'))

        for nca in self:
            if type(nca) == Nca:
                if nca.header.getCryptoType2() != newMasterKeyRev:
                    Print.info('writing masterKeyRev for %s, %d -> %s' %
                               (str(nca._path), nca.header.getCryptoType2(),
                                str(newMasterKeyRev)))

                    encKeyBlock = nca.header.getKeyBlock()

                    if sum(encKeyBlock) != 0:
                        key = Keys.keyAreaKey(
                            Keys.getMasterKeyIndex(masterKeyRev),
                            nca.header.keyIndex)
                        Print.info('decrypting with %s (%d, %d)' %
                                   (str(hx(key)),
                                    Keys.getMasterKeyIndex(masterKeyRev),
                                    nca.header.keyIndex))
                        crypto = aes128.AESECB(key)
                        decKeyBlock = crypto.decrypt(encKeyBlock)

                        key = Keys.keyAreaKey(
                            Keys.getMasterKeyIndex(newMasterKeyRev),
                            nca.header.keyIndex)
                        Print.info('encrypting with %s (%d, %d)' %
                                   (str(hx(key)),
                                    Keys.getMasterKeyIndex(newMasterKeyRev),
                                    nca.header.keyIndex))
                        crypto = aes128.AESECB(key)

                        reEncKeyBlock = crypto.encrypt(decKeyBlock)
                        nca.header.setKeyBlock(reEncKeyBlock)

                    if newMasterKeyRev >= 3:
                        nca.header.setCryptoType(2)
                        nca.header.setCryptoType2(newMasterKeyRev)
                    else:
                        nca.header.setCryptoType(newMasterKeyRev)
                        nca.header.setCryptoType2(0)
コード例 #2
0
ファイル: Nca.py プロジェクト: jeffangama/nut
    def verifyKey(self, userkey):
        if not self.header.hasTitleRights():
            titleKeyDec = Keys.decryptTitleKey(
                file.getTitleKeyBlock().to_bytes(16, byteorder='big'),
                Keys.getMasterKeyIndex(self.masterKey()))
        else:
            encKey = userkey

            titleKeyDec = Keys.decryptTitleKey(
                encKey, Keys.getMasterKeyIndex(self.masterKey()))
            '''
			print('\nTesting {} with:'.format(self))
			print('- Keygeneration {}'.format(self.masterKey()))			
			print('- Encrypted key {}'.format(str(hx(encKey))[2:-1]))
			print('- Decrypted key {}'.format(str(hx(titleKeyDec))[2:-1]))
			'''

        decKey = titleKeyDec
        f = self

        if self.header.getRightsId() != 0:
            for fs in self:
                #print(fs.fsType)
                #print(fs.cryptoType)
                if fs.fsType == Type.Fs.PFS0 and fs.cryptoType == Type.Crypto.CTR:
                    f.seek(0)
                    ncaHeader = NcaHeader()
                    ncaHeader.open(
                        MemoryFile(f.read(0x400), Type.Crypto.XTS,
                                   uhx(Keys.get('header_key'))))
                    pfs0 = fs
                    sectionHeaderBlock = fs.buffer

                    #fs.f.setKey(b'\x00' * 16)
                    #print('- Current key {}'.format(str(hx(fs.f.cryptoKey))[2:-1]))

                    fs.seek(0)
                    pfs0Offset = 0  #int.from_bytes(sectionHeaderBlock[0x38:0x40], byteorder='little', signed=False)
                    pfs0Header = fs.read(0x10)

                    #Hex.dump(sectionHeaderBlock)
                    #mem = MemoryFile(pfs0Header, Type.Crypto.CTR, decKey, pfs0.cryptoCounter, offset = pfs0Offset)
                    data = pfs0Header  #mem.read();
                    #Hex.dump(pfs0Header)
                    magic = data[0:4]
                    #print(magic)
                    if magic != b'PFS0':
                        return False
                    else:
                        return True

                if fs.fsType == Type.Fs.ROMFS and fs.cryptoType == Type.Crypto.CTR:
                    f.seek(0)
                    ncaHeader = NcaHeader()
                    ncaHeader.open(
                        MemoryFile(f.read(0x400), Type.Crypto.XTS,
                                   uhx(Keys.get('header_key'))))
                    ncaHeader = f.read(0x400)
                    pfs0 = fs
                    sectionHeaderBlock = fs.buffer

                    levelOffset = int.from_bytes(sectionHeaderBlock[0x18:0x20],
                                                 byteorder='little',
                                                 signed=False)
                    levelSize = int.from_bytes(sectionHeaderBlock[0x20:0x28],
                                               byteorder='little',
                                               signed=False)

                    pfs0Offset = levelOffset
                    f.seek(pfs0Offset + fs.f.offset)
                    pfs0Header = f.read(levelSize)

                    #fs.seek(pfs0Offset)
                    #pfs0Header = fs.read(levelSize)

                    #print(sectionHeaderBlock[8:12] == b'IVFC')
                    if sectionHeaderBlock[8:12] == b'IVFC':
                        #Hex.dump(sectionHeaderBlock)
                        #Print.info(hx(sectionHeaderBlock[0xc8:0xc8+0x20]).decode('utf-8'))
                        mem = MemoryFile(pfs0Header,
                                         Type.Crypto.CTR,
                                         decKey,
                                         pfs0.cryptoCounter,
                                         offset=fs.f.offset)

                        data = mem.read()

                        #Hex.dump(data, 48)
                        #print('hash = %s' % str(sha256(data).hexdigest()))
                        if hx(sectionHeaderBlock[0xc8:0xc8 +
                                                 0x20]).decode('utf-8') == str(
                                                     sha256(data).hexdigest()):
                            return True
                        else:
                            return False
                    else:
                        mem = MemoryFile(pfs0Header,
                                         Type.Crypto.CTR,
                                         decKey,
                                         pfs0.cryptoCounter,
                                         offset=pfs0Offset)
                        data = mem.read()
                        #Hex.dump(data)
                        magic = mem.read()[0:4]
                        #print(magic)
                        if magic != b'PFS0':
                            pass
                        else:
                            return True

                if fs.fsType == Type.Fs.ROMFS and fs.cryptoType == Type.Crypto.BKTR and str(
                        f.header.contentType) == 'Content.PROGRAM':
                    f.seek(0)
                    ncaHeader = NcaHeader()
                    ncaHeader.open(
                        MemoryFile(f.read(0x400), Type.Crypto.XTS,
                                   uhx(Keys.get('header_key'))))
                    ncaHeader = f.read(0x400)
                    pfs0 = fs
                    sectionHeaderBlock = fs.buffer

                    levelOffset = int.from_bytes(sectionHeaderBlock[0x18:0x20],
                                                 byteorder='little',
                                                 signed=False)
                    levelSize = int.from_bytes(sectionHeaderBlock[0x20:0x28],
                                               byteorder='little',
                                               signed=False)

                    pfs0Offset = fs.offset + levelOffset
                    f.seek(pfs0Offset)
                    pfs0Header = f.read(levelSize)

                    if sectionHeaderBlock[8:12] == b'IVFC':
                        for i in range(10):
                            ini = 0x100 + (i * 0x10)
                            fin = 0x110 + (i * 4)
                            test = sectionHeaderBlock[ini:fin]
                            if test == b'BKTR':
                                return True
        return False