Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add many classes that are used for NCA reading #244

Merged
merged 24 commits into from
Apr 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
800d14f
Add more assertion options
Thealexbarney Mar 2, 2022
cd2b8ed
Skeleton AesXtsStorage
Thealexbarney Mar 2, 2022
b9e2e08
Add NcaReader and some related NCA classes
Thealexbarney Mar 2, 2022
c9352fc
Make AES crypto return the number of bytes written
Thealexbarney Mar 3, 2022
e8d5415
Add AesCtrStorage
Thealexbarney Mar 5, 2022
0081973
Add AesCtrCounterExtendedStorage
Thealexbarney Mar 5, 2022
3e64f9e
Skeleton NcaFileSystemDriver
Thealexbarney Mar 7, 2022
d28c38a
Add MemoryResourceBufferHoldStorage
Thealexbarney Mar 9, 2022
c765ab9
Rename StorageType to StorageLayoutType
Thealexbarney Mar 10, 2022
eaff805
Skeleton BlockCacheBufferedStorage
Thealexbarney Mar 11, 2022
2c154ec
Implement AlignmentMatchingStorage classes
Thealexbarney Mar 12, 2022
3a05e77
Add ReadOnlyBlockCacheStorage
Thealexbarney Mar 14, 2022
4e5e9a4
Add memory fence functions
Thealexbarney Apr 11, 2022
e46c1f0
Add multiple wait APIs
Thealexbarney Apr 11, 2022
7dd137d
Add os::Semaphore
Thealexbarney Apr 11, 2022
fc3fb18
Update IStorage range check functions for 14.0.0
Thealexbarney Apr 14, 2022
398a142
Update some Nca classes for 14.0.0
Thealexbarney Apr 17, 2022
2241a7c
Update AesCtrCounterExtendedStorage for 14.0.0
Thealexbarney Apr 17, 2022
b54f5d1
Add IntegrityVerificationStorage
Thealexbarney Apr 18, 2022
6c9e6e5
Add HierarchicalIntegrityVerificationStorage
Thealexbarney Apr 19, 2022
28a4deb
Add FatFileSystemCreator
Thealexbarney Apr 19, 2022
b5ae212
Mark some classes as being updated for 14.1.0
Thealexbarney Apr 19, 2022
f8b9c35
Add IntegrityRomFsStorage
Thealexbarney Apr 19, 2022
99ad308
Add SwitchStorage and RegionSwitchStorage
Thealexbarney Apr 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions build/CodeGen/results.csv
Original file line number Diff line number Diff line change
Expand Up @@ -996,10 +996,10 @@ Module,DescriptionStart,DescriptionEnd,Flags,Namespace,Name,Summary
2,6316,,,,UnsupportedSetSizeForHierarchicalIntegrityVerificationStorage,
2,6317,,,,UnsupportedOperateRangeForHierarchicalIntegrityVerificationStorage,
2,6318,,,,UnsupportedSetSizeForIntegrityVerificationStorage,
2,6319,,,,UnsupportedOperateRangeForNonSaveDataIntegrityVerificationStorage,
2,6319,,,,UnsupportedOperateRangeForWritableIntegrityVerificationStorage,
2,6320,,,,UnsupportedOperateRangeForIntegrityVerificationStorage,
2,6321,,,,UnsupportedSetSizeForBlockCacheBufferedStorage,
2,6322,,,,UnsupportedOperateRangeForNonSaveDataBlockCacheBufferedStorage,
2,6322,,,,UnsupportedOperateRangeForWritableBlockCacheBufferedStorage,
2,6323,,,,UnsupportedOperateRangeForBlockCacheBufferedStorage,
2,6324,,,,UnsupportedWriteForIndirectStorage,
2,6325,,,,UnsupportedSetSizeForIndirectStorage,
Expand Down Expand Up @@ -1064,6 +1064,9 @@ Module,DescriptionStart,DescriptionEnd,Flags,Namespace,Name,Summary
2,6386,,,,UnsupportedSetSizeForZeroBitmapHashStorageFile,
2,6387,,,,UnsupportedWriteForCompressedStorage,
2,6388,,,,UnsupportedOperateRangeForCompressedStorage,
2,6395,,,,UnsupportedRollbackOnlyModifiedForApplicationTemporaryFileSystem,
2,6396,,,,UnsupportedRollbackOnlyModifiedForDirectorySaveDataFileSystem,
2,6397,,,,UnsupportedOperateRangeForRegionSwitchStorage,

2,6400,6449,,,PermissionDenied,
2,6403,,,,PermissionDeniedForCreateHostFileSystem,Returned when opening a host FS on a retail device.
Expand Down
2 changes: 1 addition & 1 deletion src/LibHac/Boot/Package1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ private Result SetPk11Storage()
return Result.Success;
}

private delegate void Decryptor(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key,
private delegate int Decryptor(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key,
ReadOnlySpan<byte> iv, bool preferDotNetCrypto = false);

private bool TryFindEristaKeyRevision()
Expand Down
31 changes: 31 additions & 0 deletions src/LibHac/Common/FixedArrays/Array68.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma warning disable CS0169, CS0649, IDE0051 // Field is never used, Field is never assigned to, Remove unused private members
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace LibHac.Common.FixedArrays;

public struct Array68<T>
{
public const int Length = 68;

private Array64<T> _0;
private Array4<T> _64;

public ref T this[int i] => ref Items[i];

public Span<T> Items
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.Items), Length);
}

public readonly ReadOnlySpan<T> ItemsRo
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.ItemsRo), Length);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator ReadOnlySpan<T>(in Array68<T> value) => value.ItemsRo;
}
31 changes: 31 additions & 0 deletions src/LibHac/Common/FixedArrays/Array96.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma warning disable CS0169, CS0649, IDE0051 // Field is never used, Field is never assigned to, Remove unused private members
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace LibHac.Common.FixedArrays;

public struct Array96<T>
{
public const int Length = 96;

private Array80<T> _0;
private Array16<T> _80;

public ref T this[int i] => ref Items[i];

public Span<T> Items
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.Items), Length);
}

public readonly ReadOnlySpan<T> ItemsRo
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => SpanHelpers.CreateSpan(ref MemoryMarshal.GetReference(_0.ItemsRo), Length);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator ReadOnlySpan<T>(in Array96<T> value) => value.ItemsRo;
}
58 changes: 25 additions & 33 deletions src/LibHac/Crypto/Aes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,140 +102,132 @@ public static ICipherWithIv CreateXtsEncryptor(ReadOnlySpan<byte> key1, ReadOnly
return new AesXtsEncryptor(key1, key2, iv);
}

public static void EncryptEcb128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key,
public static int EncryptEcb128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key,
bool preferDotNetCrypto = false)
{
if (IsAesNiSupported() && !preferDotNetCrypto)
{
Unsafe.SkipInit(out AesEcbModeNi cipherNi);

cipherNi.Initialize(key, false);
cipherNi.Encrypt(input, output);
return;
return cipherNi.Encrypt(input, output);
}

ICipher cipher = CreateEcbEncryptor(key, preferDotNetCrypto);

cipher.Transform(input, output);
return cipher.Transform(input, output);
}

public static void DecryptEcb128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key,
public static int DecryptEcb128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key,
bool preferDotNetCrypto = false)
{
if (IsAesNiSupported() && !preferDotNetCrypto)
{
Unsafe.SkipInit(out AesEcbModeNi cipherNi);

cipherNi.Initialize(key, true);
cipherNi.Decrypt(input, output);
return;
return cipherNi.Decrypt(input, output);
}

ICipher cipher = CreateEcbDecryptor(key, preferDotNetCrypto);

cipher.Transform(input, output);
return cipher.Transform(input, output);
}

public static void EncryptCbc128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key,
public static int EncryptCbc128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key,
ReadOnlySpan<byte> iv, bool preferDotNetCrypto = false)
{
if (IsAesNiSupported() && !preferDotNetCrypto)
{
Unsafe.SkipInit(out AesCbcModeNi cipherNi);

cipherNi.Initialize(key, iv, false);
cipherNi.Encrypt(input, output);
return;
return cipherNi.Encrypt(input, output);
}

ICipher cipher = CreateCbcEncryptor(key, iv, preferDotNetCrypto);

cipher.Transform(input, output);
return cipher.Transform(input, output);
}

public static void DecryptCbc128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key,
public static int DecryptCbc128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key,
ReadOnlySpan<byte> iv, bool preferDotNetCrypto = false)
{
if (IsAesNiSupported() && !preferDotNetCrypto)
{
Unsafe.SkipInit(out AesCbcModeNi cipherNi);

cipherNi.Initialize(key, iv, true);
cipherNi.Decrypt(input, output);
return;
return cipherNi.Decrypt(input, output);
}

ICipher cipher = CreateCbcDecryptor(key, iv, preferDotNetCrypto);

cipher.Transform(input, output);
return cipher.Transform(input, output);
}

public static void EncryptCtr128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key,
public static int EncryptCtr128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key,
ReadOnlySpan<byte> iv, bool preferDotNetCrypto = false)
{
if (IsAesNiSupported() && !preferDotNetCrypto)
{
Unsafe.SkipInit(out AesCtrModeNi cipherNi);

cipherNi.Initialize(key, iv);
cipherNi.Transform(input, output);
return;
return cipherNi.Transform(input, output);
}

ICipher cipher = CreateCtrEncryptor(key, iv, preferDotNetCrypto);

cipher.Transform(input, output);
return cipher.Transform(input, output);
}

public static void DecryptCtr128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key,
public static int DecryptCtr128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key,
ReadOnlySpan<byte> iv, bool preferDotNetCrypto = false)
{
if (IsAesNiSupported() && !preferDotNetCrypto)
{
Unsafe.SkipInit(out AesCtrModeNi cipherNi);

cipherNi.Initialize(key, iv);
cipherNi.Transform(input, output);
return;
return cipherNi.Transform(input, output);
}

ICipher cipher = CreateCtrDecryptor(key, iv, preferDotNetCrypto);

cipher.Transform(input, output);
return cipher.Transform(input, output);
}

public static void EncryptXts128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key1,
public static int EncryptXts128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key1,
ReadOnlySpan<byte> key2, ReadOnlySpan<byte> iv, bool preferDotNetCrypto = false)
{
if (IsAesNiSupported() && !preferDotNetCrypto)
{
Unsafe.SkipInit(out AesXtsModeNi cipherNi);

cipherNi.Initialize(key1, key2, iv, false);
cipherNi.Encrypt(input, output);
return;
return cipherNi.Encrypt(input, output);
}

ICipher cipher = CreateXtsEncryptor(key1, key2, iv, preferDotNetCrypto);

cipher.Transform(input, output);
return cipher.Transform(input, output);
}

public static void DecryptXts128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key1,
public static int DecryptXts128(ReadOnlySpan<byte> input, Span<byte> output, ReadOnlySpan<byte> key1,
ReadOnlySpan<byte> key2, ReadOnlySpan<byte> iv, bool preferDotNetCrypto = false)
{
if (IsAesNiSupported() && !preferDotNetCrypto)
{
Unsafe.SkipInit(out AesXtsModeNi cipherNi);

cipherNi.Initialize(key1, key2, iv, true);
cipherNi.Decrypt(input, output);
return;
return cipherNi.Decrypt(input, output);
}

ICipher cipher = CreateXtsDecryptor(key1, key2, iv, preferDotNetCrypto);

cipher.Transform(input, output);
return cipher.Transform(input, output);
}

/// <summary>
Expand Down Expand Up @@ -307,4 +299,4 @@ private static void LeftShiftBytes(ReadOnlySpan<byte> input, Span<byte> output)
carry = (byte)((b & 0xff00) >> 8);
}
}
}
}
10 changes: 5 additions & 5 deletions src/LibHac/Crypto/AesCbcCipher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ public AesCbcEncryptor(ReadOnlySpan<byte> key, ReadOnlySpan<byte> iv)
_baseCipher.Initialize(key, iv, false);
}

public void Transform(ReadOnlySpan<byte> input, Span<byte> output)
public int Transform(ReadOnlySpan<byte> input, Span<byte> output)
{
_baseCipher.Encrypt(input, output);
return _baseCipher.Encrypt(input, output);
}
}

Expand All @@ -29,8 +29,8 @@ public AesCbcDecryptor(ReadOnlySpan<byte> key, ReadOnlySpan<byte> iv)
_baseCipher.Initialize(key, iv, true);
}

public void Transform(ReadOnlySpan<byte> input, Span<byte> output)
public int Transform(ReadOnlySpan<byte> input, Span<byte> output)
{
_baseCipher.Decrypt(input, output);
return _baseCipher.Decrypt(input, output);
}
}
}
10 changes: 5 additions & 5 deletions src/LibHac/Crypto/AesCbcCipherNi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ public AesCbcEncryptorNi(ReadOnlySpan<byte> key, ReadOnlySpan<byte> iv)
_baseCipher.Initialize(key, iv, false);
}

public void Transform(ReadOnlySpan<byte> input, Span<byte> output)
public int Transform(ReadOnlySpan<byte> input, Span<byte> output)
{
_baseCipher.Encrypt(input, output);
return _baseCipher.Encrypt(input, output);
}
}

Expand All @@ -36,8 +36,8 @@ public AesCbcDecryptorNi(ReadOnlySpan<byte> key, ReadOnlySpan<byte> iv)
_baseCipher.Initialize(key, iv, true);
}

public void Transform(ReadOnlySpan<byte> input, Span<byte> output)
public int Transform(ReadOnlySpan<byte> input, Span<byte> output)
{
_baseCipher.Decrypt(input, output);
return _baseCipher.Decrypt(input, output);
}
}
}
6 changes: 3 additions & 3 deletions src/LibHac/Crypto/AesCtrCipher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public AesCtrCipher(ReadOnlySpan<byte> key, ReadOnlySpan<byte> iv)
_baseCipher.Initialize(key, iv);
}

public void Transform(ReadOnlySpan<byte> input, Span<byte> output)
public int Transform(ReadOnlySpan<byte> input, Span<byte> output)
{
_baseCipher.Transform(input, output);
return _baseCipher.Transform(input, output);
}
}
}
6 changes: 3 additions & 3 deletions src/LibHac/Crypto/AesCtrCipherNi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ public AesCtrCipherNi(ReadOnlySpan<byte> key, ReadOnlySpan<byte> iv)
_baseCipher.Initialize(key, iv);
}

public void Transform(ReadOnlySpan<byte> input, Span<byte> output)
public int Transform(ReadOnlySpan<byte> input, Span<byte> output)
{
_baseCipher.Transform(input, output);
return _baseCipher.Transform(input, output);
}
}
}
10 changes: 5 additions & 5 deletions src/LibHac/Crypto/AesEcbCipher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ public AesEcbEncryptor(ReadOnlySpan<byte> key)
_baseCipher.Initialize(key, false);
}

public void Transform(ReadOnlySpan<byte> input, Span<byte> output)
public int Transform(ReadOnlySpan<byte> input, Span<byte> output)
{
_baseCipher.Encrypt(input, output);
return _baseCipher.Encrypt(input, output);
}
}

Expand All @@ -29,8 +29,8 @@ public AesEcbDecryptor(ReadOnlySpan<byte> key)
_baseCipher.Initialize(key, true);
}

public void Transform(ReadOnlySpan<byte> input, Span<byte> output)
public int Transform(ReadOnlySpan<byte> input, Span<byte> output)
{
_baseCipher.Decrypt(input, output);
return _baseCipher.Decrypt(input, output);
}
}
}
10 changes: 5 additions & 5 deletions src/LibHac/Crypto/AesEcbCipherNi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ public AesEcbEncryptorNi(ReadOnlySpan<byte> key)
_baseCipher.Initialize(key, false);
}

public void Transform(ReadOnlySpan<byte> input, Span<byte> output)
public int Transform(ReadOnlySpan<byte> input, Span<byte> output)
{
_baseCipher.Encrypt(input, output);
return _baseCipher.Encrypt(input, output);
}
}

Expand All @@ -29,8 +29,8 @@ public AesEcbDecryptorNi(ReadOnlySpan<byte> key)
_baseCipher.Initialize(key, true);
}

public void Transform(ReadOnlySpan<byte> input, Span<byte> output)
public int Transform(ReadOnlySpan<byte> input, Span<byte> output)
{
_baseCipher.Decrypt(input, output);
return _baseCipher.Decrypt(input, output);
}
}
}
Loading