def generateKek(src, masterKey, kek_seed, key_seed): kek = [] src_kek = [] crypto = aes128.AESECB(masterKey) kek = crypto.decrypt(kek_seed) crypto = aes128.AESECB(kek) src_kek = crypto.decrypt(src) if key_seed != None: crypto = aes128.AESECB(src_kek) return crypto.decrypt(key_seed) else: return src_kek
def unwrapAesWrappedTitlekey(wrappedKey, keyGeneration): aes_kek_generation_source = getKey('aes_kek_generation_source') aes_key_generation_source = getKey('aes_key_generation_source') kek = generateKek(getKey('key_area_key_application_source'), getMasterKey(keyGeneration), aes_kek_generation_source, aes_key_generation_source) crypto = aes128.AESECB(kek) return crypto.decrypt(wrappedKey)
def load(fileName): try: global keyAreaKeys global titleKeks global loadedKeysFile loadedKeysFile = fileName with open(fileName, encoding="utf8") as f: for line in f.readlines(): r = re.match('\s*([a-z0-9_]+)\s*=\s*([A-F0-9]+)\s*', line, re.I) if r: keys[r.group(1)] = r.group(2) aes_kek_generation_source = getKey('aes_kek_generation_source') aes_key_generation_source = getKey('aes_key_generation_source') titlekek_source = getKey('titlekek_source') key_area_key_application_source = getKey( 'key_area_key_application_source') key_area_key_ocean_source = getKey('key_area_key_ocean_source') key_area_key_system_source = getKey('key_area_key_system_source') keyAreaKeys = [] for i in range(32): keyAreaKeys.append([None, None, None]) for i in range(32): if not existsMasterKey(i): continue masterKey = getMasterKey(i) crypto = aes128.AESECB(masterKey) titleKeks.append(crypto.decrypt(titlekek_source).hex()) keyAreaKeys[i][0] = generateKek(key_area_key_application_source, masterKey, aes_kek_generation_source, aes_key_generation_source) keyAreaKeys[i][1] = generateKek(key_area_key_ocean_source, masterKey, aes_kek_generation_source, aes_key_generation_source) keyAreaKeys[i][2] = generateKek(key_area_key_system_source, masterKey, aes_kek_generation_source, aes_key_generation_source) except BaseException as e: Print.error(format_exc()) Print.error(str(e))
def removeTitleRights(self): if not Titles.contains(self.titleId): raise IOError('No title key found in database! ' + self.titleId) ticket = self.ticket() masterKeyRev = ticket.getMasterKeyRevision() titleKeyDec = Keys.decryptTitleKey( ticket.getTitleKeyBlock().to_bytes(16, byteorder='big'), Keys.getMasterKeyIndex(masterKeyRev)) rightsId = ticket.getRightsId() Print.info('rightsId =\t' + hex(rightsId)) Print.info('titleKeyDec =\t' + str(hx(titleKeyDec))) 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.setRightsId(0) for nca in self: if type(nca) == Nca: if nca.header.getRightsId() == 0: continue kek = Keys.keyAreaKey(Keys.getMasterKeyIndex(masterKeyRev), nca.header.keyIndex) Print.info('writing masterKeyRev for %s, %d' % (str(nca._path), masterKeyRev)) Print.info('kek =\t' + hx(kek).decode()) crypto = aes128.AESECB(kek) encKeyBlock = crypto.encrypt(titleKeyDec * 4) nca.header.setRightsId(0) nca.header.setKeyBlock(encKeyBlock) Hex.dump(encKeyBlock)
def encryptTitleKey(key, i): kek = getTitleKek(i) crypto = aes128.AESECB(uhx(kek)) return crypto.encrypt(key)
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)