Use fixed array structs instead of Data* structs

This commit is contained in:
Alex Barney 2021-12-29 10:06:02 -07:00
parent 53e5029ef4
commit 5013e7d2ec
9 changed files with 114 additions and 105 deletions

View File

@ -99,46 +99,46 @@ public static class KeysCodeGen
RSAParameters betaNca0Params =
Rsa.RecoverParameters(BetaNca0Modulus, StandardPublicExponent, BetaNca0Exponent);
betaNca0Params.D.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.PrivateExponent.Data);
betaNca0Params.DP.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.Dp.Data);
betaNca0Params.DQ.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.Dq.Data);
betaNca0Params.Exponent.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.PublicExponent.Data);
betaNca0Params.InverseQ.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.InverseQ.Data);
betaNca0Params.Modulus.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.Modulus.Data);
betaNca0Params.P.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.P.Data);
betaNca0Params.Q.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.Q.Data);
betaNca0Params.D.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.PrivateExponent.Items);
betaNca0Params.DP.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.Dp.Items);
betaNca0Params.DQ.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.Dq.Items);
betaNca0Params.Exponent.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.PublicExponent.Items);
betaNca0Params.InverseQ.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.InverseQ.Items);
betaNca0Params.Modulus.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.Modulus.Items);
betaNca0Params.P.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.P.Items);
betaNca0Params.Q.AsSpan().CopyTo(keySet.BetaNca0KeyAreaKey.Q.Items);
// First populate the prod RSA keys
keySet.SetMode(KeySet.Mode.Prod);
StandardPublicExponent.CopyTo(keySet.NcaHeaderSigningKeys[0].PublicExponent.Data);
StandardPublicExponent.CopyTo(keySet.NcaHeaderSigningKeys[1].PublicExponent.Data);
NcaHdrFixedKeyModulus0Prod.CopyTo(keySet.NcaHeaderSigningKeys[0].Modulus.Data);
NcaHdrFixedKeyModulus1Prod.CopyTo(keySet.NcaHeaderSigningKeys[1].Modulus.Data);
StandardPublicExponent.CopyTo(keySet.NcaHeaderSigningKeys[0].PublicExponent.Items);
StandardPublicExponent.CopyTo(keySet.NcaHeaderSigningKeys[1].PublicExponent.Items);
NcaHdrFixedKeyModulus0Prod.CopyTo(keySet.NcaHeaderSigningKeys[0].Modulus.Items);
NcaHdrFixedKeyModulus1Prod.CopyTo(keySet.NcaHeaderSigningKeys[1].Modulus.Items);
StandardPublicExponent.CopyTo(keySet.AcidSigningKeys[0].PublicExponent.Data);
StandardPublicExponent.CopyTo(keySet.AcidSigningKeys[1].PublicExponent.Data);
AcidFixedKeyModulus0Prod.CopyTo(keySet.AcidSigningKeys[0].Modulus.Data);
AcidFixedKeyModulus1Prod.CopyTo(keySet.AcidSigningKeys[1].Modulus.Data);
StandardPublicExponent.CopyTo(keySet.AcidSigningKeys[0].PublicExponent.Items);
StandardPublicExponent.CopyTo(keySet.AcidSigningKeys[1].PublicExponent.Items);
AcidFixedKeyModulus0Prod.CopyTo(keySet.AcidSigningKeys[0].Modulus.Items);
AcidFixedKeyModulus1Prod.CopyTo(keySet.AcidSigningKeys[1].Modulus.Items);
StandardPublicExponent.CopyTo(keySet.Package2SigningKey.PublicExponent.Data);
Package2FixedKeyModulusProd.CopyTo(keySet.Package2SigningKey.Modulus.Data);
StandardPublicExponent.CopyTo(keySet.Package2SigningKey.PublicExponent.Items);
Package2FixedKeyModulusProd.CopyTo(keySet.Package2SigningKey.Modulus.Items);
// Populate the dev RSA keys
keySet.SetMode(KeySet.Mode.Dev);
StandardPublicExponent.CopyTo(keySet.NcaHeaderSigningKeys[0].PublicExponent.Data);
StandardPublicExponent.CopyTo(keySet.NcaHeaderSigningKeys[1].PublicExponent.Data);
NcaHdrFixedKeyModulus0Dev.CopyTo(keySet.NcaHeaderSigningKeys[0].Modulus.Data);
NcaHdrFixedKeyModulus1Dev.CopyTo(keySet.NcaHeaderSigningKeys[1].Modulus.Data);
StandardPublicExponent.CopyTo(keySet.NcaHeaderSigningKeys[0].PublicExponent.Items);
StandardPublicExponent.CopyTo(keySet.NcaHeaderSigningKeys[1].PublicExponent.Items);
NcaHdrFixedKeyModulus0Dev.CopyTo(keySet.NcaHeaderSigningKeys[0].Modulus.Items);
NcaHdrFixedKeyModulus1Dev.CopyTo(keySet.NcaHeaderSigningKeys[1].Modulus.Items);
StandardPublicExponent.CopyTo(keySet.AcidSigningKeys[0].PublicExponent.Data);
StandardPublicExponent.CopyTo(keySet.AcidSigningKeys[1].PublicExponent.Data);
AcidFixedKeyModulus0Dev.CopyTo(keySet.AcidSigningKeys[0].Modulus.Data);
AcidFixedKeyModulus1Dev.CopyTo(keySet.AcidSigningKeys[1].Modulus.Data);
StandardPublicExponent.CopyTo(keySet.AcidSigningKeys[0].PublicExponent.Items);
StandardPublicExponent.CopyTo(keySet.AcidSigningKeys[1].PublicExponent.Items);
AcidFixedKeyModulus0Dev.CopyTo(keySet.AcidSigningKeys[0].Modulus.Items);
AcidFixedKeyModulus1Dev.CopyTo(keySet.AcidSigningKeys[1].Modulus.Items);
StandardPublicExponent.CopyTo(keySet.Package2SigningKey.PublicExponent.Data);
Package2FixedKeyModulusDev.CopyTo(keySet.Package2SigningKey.Modulus.Data);
StandardPublicExponent.CopyTo(keySet.Package2SigningKey.PublicExponent.Items);
Package2FixedKeyModulusDev.CopyTo(keySet.Package2SigningKey.Modulus.Items);
return keySet;
}

View File

@ -225,8 +225,8 @@ public class KeySet
{
return new RSAParameters
{
Exponent = key.PublicExponent.DataRo.ToArray(),
Modulus = key.Modulus.DataRo.ToArray()
Exponent = key.PublicExponent.ItemsRo.ToArray(),
Modulus = key.Modulus.ItemsRo.ToArray()
};
}
@ -234,14 +234,14 @@ public class KeySet
{
return new RSAParameters
{
D = key.PrivateExponent.DataRo.ToArray(),
DP = key.Dp.DataRo.ToArray(),
DQ = key.Dq.DataRo.ToArray(),
Exponent = key.PublicExponent.DataRo.ToArray(),
InverseQ = key.InverseQ.DataRo.ToArray(),
Modulus = key.Modulus.DataRo.ToArray(),
P = key.P.DataRo.ToArray(),
Q = key.Q.DataRo.ToArray()
D = key.PrivateExponent.ItemsRo.ToArray(),
DP = key.Dp.ItemsRo.ToArray(),
DQ = key.Dq.ItemsRo.ToArray(),
Exponent = key.PublicExponent.ItemsRo.ToArray(),
InverseQ = key.InverseQ.ItemsRo.ToArray(),
Modulus = key.Modulus.ItemsRo.ToArray(),
P = key.P.ItemsRo.ToArray(),
Q = key.Q.ItemsRo.ToArray()
};
}

View File

@ -3,6 +3,7 @@ using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using LibHac.Common;
using LibHac.Common.FixedArrays;
using LibHac.Util;
namespace LibHac.Crypto;
@ -117,49 +118,21 @@ public struct AesCmac
#endif
}
[StructLayout(LayoutKind.Sequential)]
public struct RsaFullKey
{
public Data100 PrivateExponent;
public Data80 Dp;
public Data80 Dq;
public Data3 PublicExponent;
public Data80 InverseQ;
public Data100 Modulus;
public Data80 P;
public Data80 Q;
// ReSharper disable once UnassignedField.Global
public Array256<byte> PrivateExponent;
public Array128<byte> Dp;
public Array128<byte> Dq;
public Array3<byte> PublicExponent;
public Array128<byte> InverseQ;
public Array256<byte> Modulus;
public Array128<byte> P;
public Array128<byte> Q;
}
[StructLayout(LayoutKind.Sequential)]
public struct RsaKey
{
public Data100 Modulus;
public Data3 PublicExponent;
}
[StructLayout(LayoutKind.Explicit, Size = 0x100)]
public struct Data100
{
[FieldOffset(0)] private byte _byte;
public Span<byte> Data => SpanHelpers.CreateSpan(ref _byte, 0x100);
public readonly ReadOnlySpan<byte> DataRo => SpanHelpers.CreateReadOnlySpan(in _byte, 0x100);
}
[StructLayout(LayoutKind.Explicit, Size = 0x80)]
public struct Data80
{
[FieldOffset(0)] private byte _byte;
public Span<byte> Data => SpanHelpers.CreateSpan(ref _byte, 0x80);
public readonly ReadOnlySpan<byte> DataRo => SpanHelpers.CreateReadOnlySpan(in _byte, 0x80);
}
[StructLayout(LayoutKind.Explicit, Size = 3)]
public struct Data3
{
[FieldOffset(0)] private byte _byte;
public Span<byte> Data => SpanHelpers.CreateSpan(ref _byte, 3);
public readonly ReadOnlySpan<byte> DataRo => SpanHelpers.CreateReadOnlySpan(in _byte, 3);
public Array256<byte> Modulus;
public Array3<byte> PublicExponent;
}

View File

@ -1,18 +1,12 @@
using System.Runtime.InteropServices;
using LibHac.Common;
using LibHac.Common.FixedArrays;
namespace LibHac.Fat;
[StructLayout(LayoutKind.Explicit, Size = 0x20)]
public struct FatError
{
private const int FunctionNameLength = 0x10;
[FieldOffset(0x00)] public int Error;
[FieldOffset(0x04)] public int ExtraError;
[FieldOffset(0x08)] public int DriveId;
[FieldOffset(0x0C)] private byte _functionName;
public U8SpanMutable ErrorName =>
new U8SpanMutable(SpanHelpers.CreateSpan(ref _functionName, FunctionNameLength));
public int Error;
public int ExtraError;
public int DriveId;
public Array16<byte> ErrorName;
public int Reserved;
}

View File

@ -11,7 +11,7 @@ namespace LibHac.Fs.Fsa;
public static class MountUtility
{
internal static Result GetMountNameAndSubPath(out MountName mountName, out U8Span subPath, U8Span path)
private static Result GetMountNameAndSubPath(out MountName mountName, out U8Span subPath, U8Span path)
{
UnsafeHelpers.SkipParamInit(out mountName);
subPath = default;

View File

@ -1,15 +1,15 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using LibHac.Common;
using LibHac.Common.FixedArrays;
namespace LibHac.Fs;
[StructLayout(LayoutKind.Sequential, Size = 16)]
[DebuggerDisplay("{ToString()}")]
internal struct MountName
{
public Span<byte> Name => SpanHelpers.AsByteSpan(ref this);
private Array16<byte> _nameArray;
public Span<byte> Name => _nameArray.Items;
public override string ToString() => new U8Span(Name).ToString();
}

View File

@ -1,19 +1,19 @@
using System;
using LibHac.Crypto;
using LibHac.Common.FixedArrays;
namespace LibHac.FsSrv;
public class SaveDataTransferCryptoConfiguration
{
private Data100 _tokenSigningKeyModulus;
private Data100 _keySeedPackageSigningKeyModulus;
private Data100 _kekEncryptionKeyModulus;
private Data100 _keyPackageSigningModulus;
private Array256<byte> _tokenSigningKeyModulus;
private Array256<byte> _keySeedPackageSigningKeyModulus;
private Array256<byte> _kekEncryptionKeyModulus;
private Array256<byte> _keyPackageSigningModulus;
public Span<byte> TokenSigningKeyModulus => _tokenSigningKeyModulus.Data;
public Span<byte> KeySeedPackageSigningKeyModulus => _keySeedPackageSigningKeyModulus.Data;
public Span<byte> KekEncryptionKeyModulus => _kekEncryptionKeyModulus.Data;
public Span<byte> KeyPackageSigningModulus => _keyPackageSigningModulus.Data;
public Span<byte> TokenSigningKeyModulus => _tokenSigningKeyModulus.Items;
public Span<byte> KeySeedPackageSigningKeyModulus => _keySeedPackageSigningKeyModulus.Items;
public Span<byte> KekEncryptionKeyModulus => _kekEncryptionKeyModulus.Items;
public Span<byte> KeyPackageSigningModulus => _keyPackageSigningModulus.Items;
public SaveTransferAesKeyGenerator GenerateAesKey { get; set; }
public RandomDataGenerator GenerateRandomData { get; set; }

View File

@ -0,0 +1,19 @@
using System;
using System.Runtime.CompilerServices;
namespace LibHac.Tests.Common;
public class Layout
{
public static int GetOffset<TStruct, TField>(in TStruct structRef, in TField fieldRef)
{
ref TField structOffset = ref Unsafe.As<TStruct, TField>(ref Unsafe.AsRef(in structRef));
ref TField fieldOffset = ref Unsafe.AsRef(in fieldRef);
int offset = Unsafe.ByteOffset(ref structOffset, ref fieldOffset).ToInt32();
if (offset >= Unsafe.SizeOf<TStruct>())
throw new ArgumentException($"Error getting field offset. {nameof(structRef)} and {nameof(fieldRef)} must be from the same struct instance.");
return offset;
}
}

View File

@ -0,0 +1,23 @@
using System.Runtime.CompilerServices;
using LibHac.Fat;
using Xunit;
using static LibHac.Tests.Common.Layout;
namespace LibHac.Tests.Fat;
public class TypeLayoutTests
{
[Fact]
public static void FatError_Layout()
{
var s = new FatError();
Assert.Equal(0x20, Unsafe.SizeOf<FatError>());
Assert.Equal(0x00, GetOffset(in s, in s.Error));
Assert.Equal(0x04, GetOffset(in s, in s.ExtraError));
Assert.Equal(0x08, GetOffset(in s, in s.DriveId));
Assert.Equal(0x0C, GetOffset(in s, in s.ErrorName));
Assert.Equal(0x1C, GetOffset(in s, in s.Reserved));
}
}