public byte[] GetDecryptedTitleKey() { int keyRevision = Utilities.GetMasterKeyRevision(Header.KeyGeneration); byte[] titleKek = KeySet.TitleKeks[keyRevision].DataRo.ToArray(); var rightsId = new RightsId(Header.RightsId); if (KeySet.ExternalKeySet.Get(rightsId, out AccessKey accessKey).IsFailure()) { throw new MissingKeyException("Missing NCA title key.", rightsId.ToString(), KeyType.Title); } if (titleKek.IsZeros()) { string keyName = $"titlekek_{keyRevision:x2}"; throw new MissingKeyException("Unable to decrypt title key.", keyName, KeyType.Common); } byte[] encryptedKey = accessKey.Value.ToArray(); byte[] decryptedKey = new byte[Aes.KeySize128]; Aes.DecryptEcb128(encryptedKey, decryptedKey, titleKek); return(decryptedKey); }
public byte[] GetDecryptedTitleKey() { int keyRevision = Util.GetMasterKeyRevision(Header.KeyGeneration); byte[] titleKek = Keyset.TitleKeks[keyRevision]; var rightsId = new RightsId(Header.RightsId); if (Keyset.ExternalKeySet.Get(rightsId, out AccessKey accessKey).IsFailure()) { throw new MissingKeyException("Missing NCA title key.", rightsId.ToString(), KeyType.Title); } if (titleKek.IsEmpty()) { string keyName = $"titlekek_{keyRevision:x2}"; throw new MissingKeyException("Unable to decrypt title key.", keyName, KeyType.Common); } byte[] encryptedKey = accessKey.Value.ToArray(); var decryptedKey = new byte[CryptoOld.Aes128Size]; CryptoOld.DecryptEcb(titleKek, encryptedKey, decryptedKey, CryptoOld.Aes128Size); return(decryptedKey); }
private void BuildChildItems(PartitionFileSystemItemBase parentItem) { try { var partitionFileSystem = parentItem.PartitionFileSystem; var remainingEntries = new List <PartitionFileEntry>(); // First loop on *.tik files to inject title keys in KeySet foreach (var partitionFileEntry in partitionFileSystem.Files) { var fileName = partitionFileEntry.Name; if (!fileName.EndsWith(".tik", StringComparison.OrdinalIgnoreCase)) { remainingEntries.Add(partitionFileEntry); continue; } IFile file; try { file = partitionFileSystem.OpenFile(partitionFileEntry, OpenMode.Read); } catch (Exception ex) { OnLoadingException(ex, parentItem); var message = LocalizationManager.Instance.Current.Keys.LoadingError_FailedToOpenPartitionFile.SafeFormat(ex.Message); parentItem.Errors.Add(TREE_LOADING_CATEGORY, message); _logger.LogError(ex, message); continue; } Ticket ticket; try { using var asStream = file.AsStream(); ticket = new Ticket(asStream); } catch (Exception ex) { OnLoadingException(ex, parentItem); var message = LocalizationManager.Instance.Current.Keys.LoadingError_FailedToLoadTicketFile.SafeFormat(ex.Message); parentItem.Errors.Add(TREE_LOADING_CATEGORY, message); _logger.LogError(ex, message); continue; } var ticketItem = new TicketItem(ticket, partitionFileEntry, file, parentItem); try { var rightsId = new RightsId(ticket.RightsId); var accessKey = new AccessKey(ticket.TitleKeyBlock); ticketItem.RightsId = rightsId; ticketItem.AccessKey = accessKey; if (parentItem.KeySet.ExternalKeySet.Get(rightsId, out var existingAccessKey) == Result.Success) { // Here RightID key is already defined if (existingAccessKey != accessKey) { // Replaces the RightID key with the one defined in the ticket parentItem.KeySet.ExternalKeySet.Remove(rightsId); parentItem.KeySet.ExternalKeySet.Add(rightsId, accessKey).ThrowIfFailure(); _logger.LogWarning(LocalizationManager.Instance.Current.Keys.LoadingWarning_TitleIdKeyReplaced.SafeFormat(rightsId.ToString(), accessKey.ToString(), fileName, existingAccessKey)); } else { _logger.LogDebug(LocalizationManager.Instance.Current.Keys.LoadingDebug_TitleIdKeyAlreadyExists.SafeFormat(rightsId.ToString(), accessKey.ToString(), fileName)); } } else { parentItem.KeySet.ExternalKeySet.Add(rightsId, accessKey).ThrowIfFailure(); _logger.LogInformation(LocalizationManager.Instance.Current.Keys.LoadingInfo_TitleIdKeySuccessfullyInjected.SafeFormat(rightsId.ToString(), accessKey.ToString(), fileName)); } } catch (Exception ex) { _logger.LogError(ex, LocalizationManager.Instance.Current.Keys.LoadingError_FailedToLoadTitleIdKey.SafeFormat(fileName, ex.Message)); } parentItem.TicketChildItems.Add(ticketItem); } foreach (var partitionFileEntry in remainingEntries) { IFile file; try { file = partitionFileSystem.OpenFile(partitionFileEntry, OpenMode.Read); } catch (Exception ex) { OnLoadingException(ex, parentItem); var message = LocalizationManager.Instance.Current.Keys.LoadingError_FailedToOpenPartitionFile.SafeFormat(ex.Message); parentItem.Errors.Add(TREE_LOADING_CATEGORY, message); _logger.LogError(ex, message); continue; } var fileName = partitionFileEntry.Name; if (fileName.EndsWith(".nca", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".ncz", StringComparison.OrdinalIgnoreCase)) { Nca nca; try { nca = new Nca(parentItem.KeySet, new FileStorage(file)); } catch (Exception ex) { OnLoadingException(ex, parentItem); var message = LocalizationManager.Instance.Current.Keys.LoadingError_FailedToLoadNcaFile.SafeFormat(ex.Message); parentItem.Errors.Add(TREE_LOADING_CATEGORY, message); _logger.LogError(ex, message); continue; } var ncaItem = new NcaItem(nca, partitionFileEntry, file, parentItem); BuildChildItems(ncaItem); parentItem.NcaChildItems.Add(ncaItem); } else { var partitionFileEntryItem = new PartitionFileEntryItem(partitionFileEntry, file, parentItem); parentItem.PartitionFileEntryChildItems.Add(partitionFileEntryItem); } } } catch (Exception ex) { OnLoadingException(ex, parentItem); var message = LocalizationManager.Instance.Current.Keys.LoadingError_FailedToLoadPartitionFileSystemContent.SafeFormat(ex.Message); parentItem.Errors.Add(TREE_LOADING_CATEGORY, message); _logger.LogError(ex, message); } }