private static void IterateDisks() { ManagementObjectCollection disks = GetDisks(); foreach (ManagementObject disk in disks) { if (disk["Model"].ToString() == "Linux UMS disk 0 USB Device") // probably a bad way of filtering? { try { DiskInfo info = CreateDiskInfo(disk); //DiskStream diskStream = new DiskStream(DiskStream.CreateDiskInfo(disk)); impl is shit i guess Stream diskStream = new RandomAccessSectorStream(new SectorStream(new DeviceStream(info.PhysicalName, info.Length), info.SectorSize * 100)); if (InsertNAND(diskStream, true)) { CurrentDisk = info; } } catch (UnauthorizedAccessException) { Console.WriteLine("Cannot direct access drive due to lack of permissions."); } } } }
public static RSAParameters DecryptRsaKey(byte[] encryptedKey, byte[] kek) { var counter = new byte[0x10]; Array.Copy(encryptedKey, counter, 0x10); var body = new byte[0x230]; Array.Copy(encryptedKey, 0x10, body, 0, 0x230); var dec = new byte[0x230]; using (var streamDec = new RandomAccessSectorStream(new Aes128CtrStream(new MemoryStream(body), kek, counter))) { streamDec.Read(dec, 0, dec.Length); } var d = new byte[0x100]; var n = new byte[0x100]; var e = new byte[4]; Array.Copy(dec, 0, d, 0, 0x100); Array.Copy(dec, 0x100, n, 0, 0x100); Array.Copy(dec, 0x200, e, 0, 4); BigInteger dInt = GetBigInteger(d); BigInteger nInt = GetBigInteger(n); BigInteger eInt = GetBigInteger(e); RSAParameters rsaParams = RecoverRsaParameters(nInt, eInt, dInt); TestRsaKey(rsaParams); return(rsaParams); }
private void DecryptKeyblobs(IProgressReport logger = null) { var cmac = new byte[0x10]; var expectedCmac = new byte[0x10]; var counter = new byte[0x10]; for (int i = 0; i < 0x20; i++) { if (KeyblobKeys[i].IsEmpty() || KeyblobMacKeys[i].IsEmpty() || EncryptedKeyblobs[i].IsEmpty()) { continue; } Array.Copy(EncryptedKeyblobs[i], expectedCmac, 0x10); Crypto.CalculateAesCmac(KeyblobMacKeys[i], EncryptedKeyblobs[i], 0x10, cmac, 0, 0xa0); if (!Util.ArraysEqual(cmac, expectedCmac)) { logger?.LogMessage($"Warning: Keyblob MAC {i:x2} is invalid. Are SBK/TSEC key correct?"); } Array.Copy(EncryptedKeyblobs[i], 0x10, counter, 0, 0x10); using (var keyblobDec = new RandomAccessSectorStream(new Aes128CtrStream( new MemoryStream(EncryptedKeyblobs[i], 0x20, Keyblobs[i].Length), KeyblobKeys[i], counter))) { keyblobDec.Read(Keyblobs[i], 0, Keyblobs[i].Length); } } }
public Stream OpenProdInfo() { SparseStream encStream = ProdInfo.Open(); Xts xts = XtsAes128.Create(Keyset.BisKeys[0]); var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true); return(decStream); }
public NandPartition OpenUserPartition() { SparseStream encStream = User.Open(); Xts xts = XtsAes128.Create(Keyset.BisKeys[3]); var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true); var fat = new FatFileSystem(decStream, Ownership.None); return(new NandPartition(fat)); }
public Nax0(Keyset keyset, Stream stream, string sdPath, bool keepOpen) { stream.Position = 0; KeepOpen = keepOpen; ReadHeader(stream); DeriveKeys(keyset, sdPath, stream); stream.Position = 0x4000; Xts xts = XtsAes128.Create(Keys[0], Keys[1]); Stream = new RandomAccessSectorStream(new XtsSectorStream(stream, xts, 0x4000, 0x4000), keepOpen); }
public HierarchicalIntegrityVerificationStream(IntegrityVerificationInfo[] levelInfo, bool enableIntegrityChecks) { Levels = new Stream[levelInfo.Length]; EnableIntegrityChecks = enableIntegrityChecks; Levels[0] = levelInfo[0].Data; for (int i = 1; i < Levels.Length; i++) { var levelData = new IntegrityVerificationStream(levelInfo[i], Levels[i - 1], enableIntegrityChecks); Levels[i] = new RandomAccessSectorStream(levelData); } DataLevel = Levels[Levels.Length - 1]; }
public BktrCryptoStream(Stream baseStream, byte[] key, long offset, long length, long counterOffset, byte[] ctrHi, BktrSuperblock bktr) : base(baseStream, key, offset, length, counterOffset, ctrHi) { BktrHeader header = bktr.SubsectionHeader; byte[] subsectionBytes; using (var streamDec = new RandomAccessSectorStream(new Aes128CtrStream(baseStream, key, offset, length, counterOffset, ctrHi))) { streamDec.Position = header.Offset; subsectionBytes = new byte[header.Size]; streamDec.Read(subsectionBytes, 0, subsectionBytes.Length); } using (var reader = new BinaryReader(new MemoryStream(subsectionBytes))) { SubsectionBlock = new SubsectionBlock(reader); } foreach (SubsectionBucket bucket in SubsectionBlock.Buckets) { SubsectionEntries.AddRange(bucket.Entries); } // Add a subsection for the BKTR headers to make things easier var headerSubsection = new SubsectionEntry { Offset = bktr.RelocationHeader.Offset, Counter = (uint)(ctrHi[4] << 24 | ctrHi[5] << 16 | ctrHi[6] << 8 | ctrHi[7]), OffsetEnd = long.MaxValue }; SubsectionEntries.Add(headerSubsection); for (int i = 0; i < SubsectionEntries.Count - 1; i++) { SubsectionEntries[i].Next = SubsectionEntries[i + 1]; SubsectionEntries[i].OffsetEnd = SubsectionEntries[i + 1].Offset; } SubsectionOffsets = SubsectionEntries.Select(x => x.Offset).ToList(); CurrentEntry = GetSubsectionEntry(0); UpdateCounterSubsection(CurrentEntry.Counter); baseStream.Position = offset; }
public HierarchicalIntegrityVerificationStream(IntegrityVerificationInfo[] levelInfo, IntegrityCheckLevel integrityCheckLevel) { Levels = new Stream[levelInfo.Length]; IntegrityCheckLevel = integrityCheckLevel; LevelValidities = new Validity[levelInfo.Length - 1][]; IntegrityStreams = new IntegrityVerificationStream[levelInfo.Length - 1]; Levels[0] = levelInfo[0].Data; for (int i = 1; i < Levels.Length; i++) { var levelData = new IntegrityVerificationStream(levelInfo[i], Levels[i - 1], integrityCheckLevel); Levels[i] = new RandomAccessSectorStream(levelData); LevelValidities[i - 1] = levelData.BlockValidities; IntegrityStreams[i - 1] = levelData; } DataLevel = Levels[Levels.Length - 1]; }
public Package2Header(Stream stream, byte[] key) { var reader = new BinaryReader(stream); Signature = reader.ReadBytes(0x100); Counter = reader.ReadBytes(0x10); var headerStream = new RandomAccessSectorStream(new Aes128CtrStream(stream, key, 0x100, 0x100, Counter)); headerStream.Position = 0x10; reader = new BinaryReader(headerStream); for (int i = 0; i < 4; i++) { SectionCounters[i] = reader.ReadBytes(0x10); } Magic = reader.ReadAscii(4); BaseOffset = reader.ReadInt32(); reader.BaseStream.Position += 4; VersionMax = reader.ReadByte(); VersionMin = reader.ReadByte(); reader.BaseStream.Position += 2; for (int i = 0; i < 4; i++) { SectionSizes[i] = reader.ReadInt32(); } for (int i = 0; i < 4; i++) { SectionOffsets[i] = reader.ReadInt32(); } for (int i = 0; i < 4; i++) { SectionHashes[i] = reader.ReadBytes(0x20); } }
public void Open() { DiskInfo disk = SelectedDisk; var stream = new RandomAccessSectorStream(new SectorStream(new DeviceStream(disk.PhysicalName, disk.Length), disk.SectorSize * 100)); Keyset keyset = OpenKeyset(); var nand = new Nand(stream, keyset); Stream prodinfo = nand.OpenProdInfo(); var calibration = new Calibration(prodinfo); keyset.EticketExtKeyRsa = Crypto.DecryptRsaKey(calibration.EticketExtKeyRsa, keyset.EticketRsaKek); Ticket[] tickets = GetTickets(keyset, nand); using (var outStream = new StreamWriter("titlekeys.txt")) { foreach (Ticket ticket in tickets) { byte[] key = ticket.GetTitleKey(keyset); outStream.WriteLine($"{ticket.RightsId.ToHexString()},{key.ToHexString()}"); } } }