2018-07-10 01:34:46 +02:00
|
|
|
|
using System.IO;
|
2018-07-09 18:49:59 +02:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using DiscUtils;
|
|
|
|
|
using DiscUtils.Fat;
|
|
|
|
|
using DiscUtils.Partitions;
|
|
|
|
|
using DiscUtils.Streams;
|
2018-08-30 23:18:27 +02:00
|
|
|
|
using libhac.Streams;
|
2018-07-09 18:49:59 +02:00
|
|
|
|
using libhac.XTSSharp;
|
|
|
|
|
|
|
|
|
|
namespace libhac.Nand
|
|
|
|
|
{
|
|
|
|
|
public class Nand
|
|
|
|
|
{
|
2018-07-10 01:34:46 +02:00
|
|
|
|
private GuidPartitionInfo ProdInfo { get; }
|
|
|
|
|
private GuidPartitionInfo ProdInfoF { get; }
|
|
|
|
|
private GuidPartitionInfo Safe { get; }
|
|
|
|
|
private GuidPartitionInfo System { get; }
|
|
|
|
|
private GuidPartitionInfo User { get; }
|
2018-07-13 17:25:39 +02:00
|
|
|
|
public Keyset Keyset { get; }
|
2018-07-10 01:34:46 +02:00
|
|
|
|
|
|
|
|
|
public Nand(Stream stream, Keyset keyset)
|
2018-07-09 18:49:59 +02:00
|
|
|
|
{
|
|
|
|
|
var disc = new GuidPartitionTable(stream, Geometry.Null);
|
2018-07-10 01:34:46 +02:00
|
|
|
|
var partitions = disc.Partitions.Select(x => (GuidPartitionInfo)x).ToArray();
|
|
|
|
|
ProdInfo = partitions.FirstOrDefault(x => x.Name == "PRODINFO");
|
|
|
|
|
ProdInfoF = partitions.FirstOrDefault(x => x.Name == "PRODINFOF");
|
|
|
|
|
Safe = partitions.FirstOrDefault(x => x.Name == "SAFE");
|
|
|
|
|
System = partitions.FirstOrDefault(x => x.Name == "SYSTEM");
|
|
|
|
|
User = partitions.FirstOrDefault(x => x.Name == "USER");
|
|
|
|
|
Keyset = keyset;
|
|
|
|
|
}
|
2018-07-09 18:49:59 +02:00
|
|
|
|
|
2018-07-10 01:34:46 +02:00
|
|
|
|
public Stream OpenProdInfo()
|
|
|
|
|
{
|
|
|
|
|
var encStream = ProdInfo.Open();
|
|
|
|
|
var xts = XtsAes128.Create(Keyset.bis_keys[0]);
|
|
|
|
|
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
|
|
|
|
return decStream;
|
|
|
|
|
}
|
2018-07-09 18:49:59 +02:00
|
|
|
|
|
2018-07-12 03:03:09 +02:00
|
|
|
|
public NandPartition OpenProdInfoF()
|
2018-07-10 01:34:46 +02:00
|
|
|
|
{
|
|
|
|
|
var encStream = ProdInfoF.Open();
|
|
|
|
|
var xts = XtsAes128.Create(Keyset.bis_keys[0]);
|
|
|
|
|
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
|
|
|
|
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
2018-07-12 03:03:09 +02:00
|
|
|
|
return new NandPartition(fat);
|
2018-07-10 01:34:46 +02:00
|
|
|
|
}
|
2018-07-09 18:49:59 +02:00
|
|
|
|
|
2018-07-12 03:03:09 +02:00
|
|
|
|
public NandPartition OpenSafePartition()
|
2018-07-10 01:34:46 +02:00
|
|
|
|
{
|
|
|
|
|
var encStream = Safe.Open();
|
|
|
|
|
var xts = XtsAes128.Create(Keyset.bis_keys[1]);
|
|
|
|
|
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
|
|
|
|
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
2018-07-12 03:03:09 +02:00
|
|
|
|
return new NandPartition(fat);
|
2018-07-10 01:34:46 +02:00
|
|
|
|
}
|
2018-07-09 18:49:59 +02:00
|
|
|
|
|
2018-07-12 03:03:09 +02:00
|
|
|
|
public NandPartition OpenSystemPartition()
|
2018-07-10 01:34:46 +02:00
|
|
|
|
{
|
|
|
|
|
var encStream = System.Open();
|
|
|
|
|
var xts = XtsAes128.Create(Keyset.bis_keys[2]);
|
|
|
|
|
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
|
|
|
|
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
2018-07-12 03:03:09 +02:00
|
|
|
|
return new NandPartition(fat);
|
2018-07-10 01:34:46 +02:00
|
|
|
|
}
|
2018-07-09 18:49:59 +02:00
|
|
|
|
|
2018-07-12 03:03:09 +02:00
|
|
|
|
public NandPartition OpenUserPartition()
|
2018-07-10 01:34:46 +02:00
|
|
|
|
{
|
|
|
|
|
var encStream = User.Open();
|
|
|
|
|
var xts = XtsAes128.Create(Keyset.bis_keys[3]);
|
|
|
|
|
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
|
|
|
|
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
2018-07-12 03:03:09 +02:00
|
|
|
|
return new NandPartition(fat);
|
2018-07-09 18:49:59 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|