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 is not None: crypto = aes128.AESECB(src_kek) return crypto.decrypt(key_seed) else: return src_kek
def load(fileName): global keyAreaKeys global titleKeks with open(fileName, encoding="utf8") as f: for line in f.readlines(): r = re.match(r'\s*([a-z0-9_]+)\s*=\s*([A-F0-9]+)\s*', line, re.I) if r: keys[r.group(1)] = r.group(2) #crypto = aes128.AESCTR(uhx(key), uhx('00000000000000000000000000000010')) aes_kek_generation_source = uhx(keys['aes_kek_generation_source']) aes_key_generation_source = uhx(keys['aes_key_generation_source']) keyAreaKeys = [] for i in range(0x10): keyAreaKeys.append([None, None, None]) for i in range(0x10): masterKeyName = 'master_key_' + str(i).zfill(2) if masterKeyName in keys.keys(): # aes_decrypt(master_ctx, &keyset->titlekeks[i], keyset->titlekek_source, 0x10); masterKey = uhx(keys[masterKeyName]) crypto = aes128.AESECB(masterKey) titleKeks.append(crypto.decrypt(uhx(keys['titlekek_source'])).hex()) keyAreaKeys[i][0] = generateKek(uhx(keys['key_area_key_application_source']), masterKey, aes_kek_generation_source, aes_key_generation_source) keyAreaKeys[i][1] = generateKek(uhx(keys['key_area_key_ocean_source']), masterKey, aes_kek_generation_source, aes_key_generation_source) keyAreaKeys[i][2] = generateKek(uhx(keys['key_area_key_system_source']), masterKey, aes_kek_generation_source, aes_key_generation_source) keyGens.append(i) else: titleKeks.append('0' * 32)
def unwrapAesWrappedTitlekey(wrappedKey, keyGeneration): aes_kek_generation_source = uhx(keys['aes_kek_generation_source']) aes_key_generation_source = uhx(keys['aes_key_generation_source']) kek = generateKek(uhx(keys['key_area_key_application_source']), uhx(keys['master_key_' + str(keyGeneration).zfill(2)]), aes_kek_generation_source, aes_key_generation_source) crypto = aes128.AESECB(kek) return crypto.decrypt(wrappedKey)
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): global keyAreaKeys global titleKeks global hasDecimalMasterKeys with open(fileName, encoding="utf8") as f: for line in f.readlines(): r = re.match(r'\s*([a-z0-9_]+)\s*=\s*([A-F0-9]+)\s*', line, re.I) if r: keys[r.group(1).lower()] = r.group(2) #crypto = aes128.AESCTR(uhx(key), uhx('00000000000000000000000000000010')) aes_kek_generation_source = uhx(keys['aes_kek_generation_source']) aes_key_generation_source = uhx(keys['aes_key_generation_source']) digits = ['a', 'b', 'c', 'd', 'e', 'f'] for key in keys.keys(): if not key.startswith('master_key_'): continue for c in key.lower().split('_')[-1]: if c in digits: hasDecimalMasterKeys = False break keyAreaKeys = [] for i in range(0x10): keyAreaKeys.append([None, None, None]) for i in range(0x10): masterKeyName = ini_Key(i) if masterKeyName in keys.keys(): # aes_decrypt(master_ctx, &keyset->titlekeks[i], keyset->titlekek_source, 0x10); masterKey = uhx(keys[masterKeyName]) crypto = aes128.AESECB(masterKey) titleKeks.append( crypto.decrypt(uhx(keys['titlekek_source'])).hex()) keyAreaKeys[i][0] = generateKek( uhx(keys['key_area_key_application_source']), masterKey, aes_kek_generation_source, aes_key_generation_source) keyAreaKeys[i][1] = generateKek( uhx(keys['key_area_key_ocean_source']), masterKey, aes_kek_generation_source, aes_key_generation_source) keyAreaKeys[i][2] = generateKek( uhx(keys['key_area_key_system_source']), masterKey, aes_kek_generation_source, aes_key_generation_source) keyGens.append(i) else: titleKeks.append('0' * 32) keyGens.append(keyGens[-1] + 1)
def load(fileName): try: global keyAreaKeys global titleKeks global loadedKeysPath loadedKeysPath = 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 load(fileName): try: global keyAreaKeys global titleKeks 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 = uhx(keys['aes_kek_generation_source']) aes_key_generation_source = uhx(keys['aes_key_generation_source']) keyAreaKeys = [] for i in range(10): keyAreaKeys.append([None, None, None]) for i in range(10): masterKeyName = 'master_key_0' + str(i) if masterKeyName in keys.keys(): masterKey = uhx(keys[masterKeyName]) crypto = aes128.AESECB(masterKey) titleKeks.append( crypto.decrypt(uhx(keys['titlekek_source'])).hex()) keyAreaKeys[i][0] = generateKek( uhx(keys['key_area_key_application_source']), masterKey, aes_kek_generation_source, aes_key_generation_source) keyAreaKeys[i][1] = generateKek( uhx(keys['key_area_key_ocean_source']), masterKey, aes_kek_generation_source, aes_key_generation_source) keyAreaKeys[i][2] = generateKek( uhx(keys['key_area_key_system_source']), masterKey, aes_kek_generation_source, aes_key_generation_source) else: titleKeks.append('0' * 32) raise IOError( '{0} missing from keys.txt'.format(masterKeyName)) except BaseException as e: Print.error(format_exc()) Print.error(str(e))
def setStandardCryptoBuffer(self, buffer, keyGen): buffer[0x30:0x40] = b'\x00' * 0x10 emptyKey = b'\x00' * 0x10 kek = Keys.keyAreaKey(Keys.getMasterKeyIndex(keyGen), self.keyIndex) crypto = aes128.AESECB(kek) encKeyBlock = crypto.encrypt(emptyKey + emptyKey + self.titleKeyDec + emptyKey) buffer[0x100:0x140] = encKeyBlock if keyGen <= 2: buffer[0x6] = keyGen buffer[0x20] = 0 else: buffer[0x6] = 2 buffer[0x20] = keyGen return buffer
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 decrypt(key, i): crypto = aes128.AESECB(masterKey(i)) return crypto.decrypt(key)
def encryptTitleKey(key, i): kek = getTitleKek(i) crypto = aes128.AESECB(uhx(kek)) return crypto.encrypt(key)
def open(self, file=None, mode='rb', cryptoType=-1, cryptoKey=-1, cryptoCounter=-1): super(NcaHeader, self).open(file, mode, cryptoType, cryptoKey, cryptoCounter) self.rewind() self.signature1 = self.read(0x100) self.signature2 = self.read(0x100) self.magic = self.read(0x4) self.isGameCard = self.readInt8() self.contentType = self.readInt8() try: self.contentType = Fs.Type.Content(self.contentType) except: pass self.cryptoType = self.readInt8() self.keyIndex = self.readInt8() self.size = self.readInt64() self.titleId = hx(self.read(8)[::-1]).decode('utf-8').upper() self.contentIndex = self.readInt32() self.sdkVersion = self.readInt32() self.cryptoType2 = self.readInt8() self.read(0xF) # padding self.rightsId = hx(self.read(0x10)) if self.magic not in [b'NCA3', b'NCA2']: raise Exception('Failed to decrypt NCA header: ' + str(self.magic)) self.sectionHashes = [] for i in range(4): self.sectionTables.append(SectionTableEntry(self.read(0x10))) for i in range(4): self.sectionHashes.append(self.sectionTables[i]) self.masterKey = (self.cryptoType if self.cryptoType > self.cryptoType2 else self.cryptoType2) - 1 if self.masterKey < 0: self.masterKey = 0 self.encKeyBlock = self.getKeyBlock() #for i in range(4): # offset = i * 0x10 # key = encKeyBlock[offset:offset+0x10] # Print.info('enc %d: %s' % (i, hx(key))) if Keys.keyAreaKey(self.masterKey, self.keyIndex): crypto = aes128.AESECB( Keys.keyAreaKey(self.masterKey, self.keyIndex)) self.keyBlock = crypto.decrypt(self.encKeyBlock) self.keys = [] for i in range(4): offset = i * 0x10 key = self.keyBlock[offset:offset + 0x10] #Print.info('dec %d: %s' % (i, hx(key))) self.keys.append(key) else: self.keys = [None, None, None, None, None, None, None] if self.hasTitleRights(): if self.titleId.upper() in Titles.keys() and Titles.get( self.titleId.upper()).key: self.titleKeyDec = Keys.decryptTitleKey( uhx(Titles.get(self.titleId.upper()).key), self.masterKey) else: pass #Print.info('could not find title key!') else: self.titleKeyDec = self.key() return True
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)