mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Fix AesXtsFileSystem bugs and add the option to specify keys
This commit is contained in:
parent
fb7254684a
commit
2844466bbb
4 changed files with 33 additions and 9 deletions
|
@ -5,14 +5,16 @@ namespace LibHac.IO
|
||||||
{
|
{
|
||||||
public class AesXtsDirectory : IDirectory
|
public class AesXtsDirectory : IDirectory
|
||||||
{
|
{
|
||||||
public IFileSystem ParentFileSystem { get; }
|
IFileSystem IDirectory.ParentFileSystem => ParentFileSystem;
|
||||||
|
public AesXtsFileSystem ParentFileSystem { get; }
|
||||||
|
|
||||||
public string FullPath { get; }
|
public string FullPath { get; }
|
||||||
public OpenDirectoryMode Mode { get; }
|
public OpenDirectoryMode Mode { get; }
|
||||||
|
|
||||||
private IFileSystem BaseFileSystem { get; }
|
private IFileSystem BaseFileSystem { get; }
|
||||||
private IDirectory BaseDirectory { get; }
|
private IDirectory BaseDirectory { get; }
|
||||||
|
|
||||||
public AesXtsDirectory(IFileSystem parentFs, IDirectory baseDir, OpenDirectoryMode mode)
|
public AesXtsDirectory(AesXtsFileSystem parentFs, IDirectory baseDir, OpenDirectoryMode mode)
|
||||||
{
|
{
|
||||||
ParentFileSystem = parentFs;
|
ParentFileSystem = parentFs;
|
||||||
BaseDirectory = baseDir;
|
BaseDirectory = baseDir;
|
||||||
|
@ -66,7 +68,7 @@ namespace LibHac.IO
|
||||||
if (BitConverter.ToUInt32(buffer, 0) != 0x3058414E) return 0;
|
if (BitConverter.ToUInt32(buffer, 0) != 0x3058414E) return 0;
|
||||||
|
|
||||||
file.Read(buffer, 0x48);
|
file.Read(buffer, 0x48);
|
||||||
return BitConverter.ToInt32(buffer, 0);
|
return BitConverter.ToInt64(buffer, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ArgumentOutOfRangeException)
|
catch (ArgumentOutOfRangeException)
|
||||||
|
|
|
@ -31,10 +31,19 @@ namespace LibHac.IO
|
||||||
throw new ArgumentException("NAX0 key derivation failed.");
|
throw new ArgumentException("NAX0 key derivation failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
IStorage encStorage = BaseFile.AsStorage().Slice(HeaderLength, Header.Size);
|
IStorage encStorage = BaseFile.AsStorage().Slice(HeaderLength, Util.AlignUp(Header.Size, 0x10));
|
||||||
BaseStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Header.DecryptedKey1, Header.DecryptedKey2, BlockSize, true), 4, true);
|
BaseStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Header.DecryptedKey1, Header.DecryptedKey2, BlockSize, true), 4, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] GetKey()
|
||||||
|
{
|
||||||
|
var key = new byte[0x20];
|
||||||
|
Array.Copy(Header.DecryptedKey1, 0, key, 0, 0x10);
|
||||||
|
Array.Copy(Header.DecryptedKey2, 0, key, 0x10, 0x10);
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
public override int Read(Span<byte> destination, long offset)
|
public override int Read(Span<byte> destination, long offset)
|
||||||
{
|
{
|
||||||
int toRead = ValidateReadParamsAndGetSize(destination, offset);
|
int toRead = ValidateReadParamsAndGetSize(destination, offset);
|
||||||
|
|
|
@ -37,10 +37,10 @@ namespace LibHac.IO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AesXtsFileHeader(byte[] key1, byte[] key2, long fileSize, string path, byte[] kekSeed, byte[] verificationKey)
|
public AesXtsFileHeader(byte[] key, long fileSize, string path, byte[] kekSeed, byte[] verificationKey)
|
||||||
{
|
{
|
||||||
Array.Copy(key1, DecryptedKey1, 0x10);
|
Array.Copy(key, 0, DecryptedKey1, 0, 0x10);
|
||||||
Array.Copy(key2, DecryptedKey2, 0x10);
|
Array.Copy(key, 0x10, DecryptedKey2, 0, 0x10);
|
||||||
Magic = AesXtsFileMagic;
|
Magic = AesXtsFileMagic;
|
||||||
Size = fileSize;
|
Size = fileSize;
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,23 @@ namespace LibHac.IO
|
||||||
|
|
||||||
public void CreateFile(string path, long size, CreateFileOptions options)
|
public void CreateFile(string path, long size, CreateFileOptions options)
|
||||||
{
|
{
|
||||||
long containerSize = AesXtsFile.HeaderLength + Util.AlignUp(size, 0x16);
|
CreateFile(path, size, options, new byte[0x20]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="AesXtsFile"/> using the provided key.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The full path of the file to create.</param>
|
||||||
|
/// <param name="size">The initial size of the created file.</param>
|
||||||
|
/// <param name="options">Flags to control how the file is created.
|
||||||
|
/// Should usually be <see cref="CreateFileOptions.None"/></param>
|
||||||
|
/// <param name="key">The 256-bit key containing a 128-bit data key followed by a 128-bit tweak key.</param>
|
||||||
|
public void CreateFile(string path, long size, CreateFileOptions options, byte[] key)
|
||||||
|
{
|
||||||
|
long containerSize = AesXtsFile.HeaderLength + Util.AlignUp(size, 0x10);
|
||||||
BaseFileSystem.CreateFile(path, containerSize, options);
|
BaseFileSystem.CreateFile(path, containerSize, options);
|
||||||
|
|
||||||
var header = new AesXtsFileHeader(new byte[0x10], new byte[0x10], size, path, KekSource, ValidationKey);
|
var header = new AesXtsFileHeader(key, size, path, KekSource, ValidationKey);
|
||||||
|
|
||||||
using (IFile baseFile = BaseFileSystem.OpenFile(path, OpenMode.Write))
|
using (IFile baseFile = BaseFileSystem.OpenFile(path, OpenMode.Write))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue