mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Fix regression caused by decrypting multiple AES blocks at a time
This commit is contained in:
parent
dcb25713ba
commit
7f016f875b
5 changed files with 51 additions and 51 deletions
|
@ -379,29 +379,26 @@ namespace hactoolnet
|
||||||
|
|
||||||
private static void ProcessRomFs(Context ctx, Romfs romfs)
|
private static void ProcessRomFs(Context ctx, Romfs romfs)
|
||||||
{
|
{
|
||||||
using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read))
|
if (ctx.Options.ListRomFs)
|
||||||
{
|
{
|
||||||
if (ctx.Options.ListRomFs)
|
foreach (var romfsFile in romfs.Files)
|
||||||
{
|
{
|
||||||
foreach (var romfsFile in romfs.Files)
|
ctx.Logger.LogMessage(romfsFile.FullPath);
|
||||||
{
|
|
||||||
ctx.Logger.LogMessage(romfsFile.FullPath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx.Options.RomfsOut != null)
|
if (ctx.Options.RomfsOut != null)
|
||||||
|
{
|
||||||
|
using (var outFile = new FileStream(ctx.Options.RomfsOut, FileMode.Create, FileAccess.ReadWrite))
|
||||||
{
|
{
|
||||||
using (var outFile = new FileStream(ctx.Options.RomfsOut, FileMode.Create, FileAccess.ReadWrite))
|
var romfsStream = romfs.OpenRawStream();
|
||||||
{
|
romfsStream.CopyStream(outFile, romfsStream.Length, ctx.Logger);
|
||||||
var romfsStream = romfs.OpenRawStream();
|
|
||||||
romfsStream.CopyStream(outFile, romfsStream.Length, ctx.Logger);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx.Options.RomfsOutDir != null)
|
if (ctx.Options.RomfsOutDir != null)
|
||||||
{
|
{
|
||||||
romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger);
|
romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,5 +134,11 @@ namespace libhac
|
||||||
|
|
||||||
return _decryptor.TransformBlock(_tempBuffer, 0, bytesRead, buffer, offset);
|
return _decryptor.TransformBlock(_tempBuffer, 0, bytesRead, buffer, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void ValidateSizeMultiple(long value)
|
||||||
|
{
|
||||||
|
if (value % 0x10 != 0)
|
||||||
|
throw new ArgumentException($"Value needs to be a multiple of {SectorSize}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,62 +87,59 @@ namespace libhac
|
||||||
long offset = sect.Offset;
|
long offset = sect.Offset;
|
||||||
long size = sect.Size;
|
long size = sect.Size;
|
||||||
|
|
||||||
if (!raw)
|
Stream rawStream = StreamSource.CreateStream(offset, size);
|
||||||
{
|
|
||||||
switch (sect.Header.Type)
|
|
||||||
{
|
|
||||||
case SectionType.Pfs0:
|
|
||||||
offset = sect.Offset + sect.Pfs0.Superblock.Pfs0Offset;
|
|
||||||
size = sect.Pfs0.Superblock.Pfs0Size;
|
|
||||||
break;
|
|
||||||
case SectionType.Romfs:
|
|
||||||
offset = sect.Offset + sect.Header.Romfs.IvfcHeader.LevelHeaders[Romfs.IvfcMaxLevel - 1].LogicalOffset;
|
|
||||||
size = sect.Header.Romfs.IvfcHeader.LevelHeaders[Romfs.IvfcMaxLevel - 1].HashDataSize;
|
|
||||||
break;
|
|
||||||
case SectionType.Bktr:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var sectionStream = StreamSource.CreateStream(offset, size);
|
|
||||||
|
|
||||||
switch (sect.Header.CryptType)
|
switch (sect.Header.CryptType)
|
||||||
{
|
{
|
||||||
case SectionCryptType.None:
|
case SectionCryptType.None:
|
||||||
return sectionStream;
|
break;
|
||||||
case SectionCryptType.XTS:
|
case SectionCryptType.XTS:
|
||||||
break;
|
break;
|
||||||
case SectionCryptType.CTR:
|
case SectionCryptType.CTR:
|
||||||
return new RandomAccessSectorStream(new Aes128CtrStream(sectionStream, DecryptedKeys[2], offset, sect.Header.Ctr), false);
|
rawStream = new RandomAccessSectorStream(new Aes128CtrStream(rawStream, DecryptedKeys[2], offset, sect.Header.Ctr), false);
|
||||||
|
break;
|
||||||
case SectionCryptType.BKTR:
|
case SectionCryptType.BKTR:
|
||||||
var patchStream = new RandomAccessSectorStream(
|
rawStream = new RandomAccessSectorStream(
|
||||||
new BktrCryptoStream(sectionStream, DecryptedKeys[2], 0, size, offset, sect.Header.Ctr, sect.Header.Bktr),
|
new BktrCryptoStream(rawStream, DecryptedKeys[2], 0, size, offset, sect.Header.Ctr, sect.Header.Bktr),
|
||||||
false);
|
false);
|
||||||
if (BaseNca == null)
|
if (BaseNca == null)
|
||||||
{
|
{
|
||||||
return patchStream;
|
return rawStream;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var dataLevel = sect.Header.Bktr.IvfcHeader.LevelHeaders[Romfs.IvfcMaxLevel - 1];
|
|
||||||
|
|
||||||
var baseSect = BaseNca.Sections.FirstOrDefault(x => x.Type == SectionType.Romfs);
|
var baseSect = BaseNca.Sections.FirstOrDefault(x => x.Type == SectionType.Romfs);
|
||||||
if (baseSect == null) throw new InvalidDataException("Base NCA has no RomFS section");
|
if (baseSect == null) throw new InvalidDataException("Base NCA has no RomFS section");
|
||||||
|
|
||||||
var baseStream = BaseNca.OpenSection(baseSect.SectionNum, true);
|
var baseStream = BaseNca.OpenSection(baseSect.SectionNum, true);
|
||||||
var virtStreamRaw = new Bktr(patchStream, baseStream, sect);
|
rawStream = new Bktr(rawStream, baseStream, sect);
|
||||||
|
|
||||||
if (raw) return virtStreamRaw;
|
|
||||||
var virtStream = new SubStream(virtStreamRaw, dataLevel.LogicalOffset, dataLevel.HashDataSize);
|
|
||||||
return virtStream;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return sectionStream;
|
if (raw) return rawStream;
|
||||||
|
|
||||||
|
switch (sect.Header.Type)
|
||||||
|
{
|
||||||
|
case SectionType.Pfs0:
|
||||||
|
offset = sect.Pfs0.Superblock.Pfs0Offset;
|
||||||
|
size = sect.Pfs0.Superblock.Pfs0Size;
|
||||||
|
break;
|
||||||
|
case SectionType.Romfs:
|
||||||
|
offset = sect.Header.Romfs.IvfcHeader.LevelHeaders[Romfs.IvfcMaxLevel - 1].LogicalOffset;
|
||||||
|
size = sect.Header.Romfs.IvfcHeader.LevelHeaders[Romfs.IvfcMaxLevel - 1].HashDataSize;
|
||||||
|
break;
|
||||||
|
case SectionType.Bktr:
|
||||||
|
offset = sect.Header.Bktr.IvfcHeader.LevelHeaders[Romfs.IvfcMaxLevel - 1].LogicalOffset;
|
||||||
|
size = sect.Header.Bktr.IvfcHeader.LevelHeaders[Romfs.IvfcMaxLevel - 1].HashDataSize;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
return new SubStream(rawStream, offset, size);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetBaseNca(Nca baseNca) => BaseNca = baseNca;
|
public void SetBaseNca(Nca baseNca) => BaseNca = baseNca;
|
||||||
|
|
|
@ -334,7 +334,7 @@ namespace libhac.XTSSharp
|
||||||
_bufferDirty = false;
|
_bufferDirty = false;
|
||||||
_currentBufferSize = sector.Length;
|
_currentBufferSize = sector.Length;
|
||||||
CacheHits++;
|
CacheHits++;
|
||||||
_s.Position += _bufferSize;
|
_s.Position += _currentBufferSize;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ namespace libhac.XTSSharp
|
||||||
/// Validates that the size is a multiple of the sector size
|
/// Validates that the size is a multiple of the sector size
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local
|
// ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local
|
||||||
private void ValidateSizeMultiple(long value)
|
protected virtual void ValidateSizeMultiple(long value)
|
||||||
{
|
{
|
||||||
if (value % SectorSize != 0)
|
if (value % SectorSize != 0)
|
||||||
throw new ArgumentException(string.Format("Value needs to be a multiple of {0}", SectorSize));
|
throw new ArgumentException(string.Format("Value needs to be a multiple of {0}", SectorSize));
|
||||||
|
|
Loading…
Reference in a new issue