mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add GetAsicCertificate
This commit is contained in:
parent
e49523eed6
commit
283ecf81ff
8 changed files with 110 additions and 8 deletions
|
@ -50,6 +50,7 @@ namespace LibHac.Common.FixedArrays;
|
||||||
[InlineArray(640)] public struct Array640<T> { public readonly int Length => 640; private T _0; }
|
[InlineArray(640)] public struct Array640<T> { public readonly int Length => 640; private T _0; }
|
||||||
[InlineArray(768)] public struct Array768<T> { public readonly int Length => 768; private T _0; }
|
[InlineArray(768)] public struct Array768<T> { public readonly int Length => 768; private T _0; }
|
||||||
[InlineArray(769)] public struct Array769<T> { public readonly int Length => 769; private T _0; }
|
[InlineArray(769)] public struct Array769<T> { public readonly int Length => 769; private T _0; }
|
||||||
|
[InlineArray(1024)] public struct Array1024<T> { public readonly int Length => 1024; private T _0; }
|
||||||
[InlineArray(3000)] public struct Array3000<T> { public readonly int Length => 3000; private T _0; }
|
[InlineArray(3000)] public struct Array3000<T> { public readonly int Length => 3000; private T _0; }
|
||||||
[InlineArray(3438)] public struct Array3438<T> { public readonly int Length => 3438; private T _0; }
|
[InlineArray(3438)] public struct Array3438<T> { public readonly int Length => 3438; private T _0; }
|
||||||
[InlineArray(5366)] public struct Array5366<T> { public readonly int Length => 5366; private T _0; }
|
[InlineArray(5366)] public struct Array5366<T> { public readonly int Length => 5366; private T _0; }
|
||||||
|
|
|
@ -428,4 +428,12 @@ public sealed class GameCardEmulated : IGcApi
|
||||||
outErrorReportInfo = default;
|
outErrorReportInfo = default;
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Result GetAsicCertificate(out GameCardAsicCertificateSet outCertificateSet)
|
||||||
|
{
|
||||||
|
Abort.DoAbortUnless(_initialized, LibNotInitializedMessage);
|
||||||
|
|
||||||
|
outCertificateSet = default;
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -31,3 +31,11 @@ public struct GameCardIdSet
|
||||||
public CardId2 Id2;
|
public CardId2 Id2;
|
||||||
public CardId3 Id3;
|
public CardId3 Id3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct GameCardAsicCertificateSet
|
||||||
|
{
|
||||||
|
public Array1024<byte> Certificate;
|
||||||
|
public Array16<byte> SerialNumber;
|
||||||
|
public Array256<byte> PublicKeyModulus;
|
||||||
|
public Array3<byte> PublicKeyExponent;
|
||||||
|
}
|
|
@ -5,17 +5,61 @@ namespace LibHac.Gc;
|
||||||
public static class Values
|
public static class Values
|
||||||
{
|
{
|
||||||
public const int GcPageSize = 0x200;
|
public const int GcPageSize = 0x200;
|
||||||
public const int GcAsicFirmwareSize = 1024 * 30; // 30 KiB
|
|
||||||
public const int GcCardDeviceIdSize = 0x10;
|
|
||||||
public const int GcChallengeCardExistenceResponseSize = 0x58;
|
|
||||||
public const int GcCardImageHashSize = 0x20;
|
|
||||||
public const int GcDeviceCertificateSize = 0x200;
|
|
||||||
public const int GcCardKeyAreaSize = GcCardKeyAreaPageCount * GcPageSize;
|
|
||||||
public const int GcCardKeyAreaPageCount = 8;
|
public const int GcCardKeyAreaPageCount = 8;
|
||||||
public const int GcCertAreaPageAddress = 56;
|
public const int GcCardKeyAreaSize = GcCardKeyAreaPageCount * GcPageSize;
|
||||||
|
|
||||||
|
public const int GcCardHeaderPageAddress = 0;
|
||||||
|
public const int GcCardHeaderPageCount = 1;
|
||||||
|
|
||||||
|
public const int GcReservedAreaPageCount = 0x37;
|
||||||
|
|
||||||
|
public const int GcCertAreaPageAddress = GcCardHeaderPageCount + GcReservedAreaPageCount;
|
||||||
|
public const int GcDeviceCertificatePageCount = 1;
|
||||||
|
public const int GcCertAreaPageCount = 0x40;
|
||||||
|
|
||||||
|
public const int GcPackageIdSize = 8;
|
||||||
|
public const int GcPartitionFsHeaderHashSize = 0x20;
|
||||||
|
public const int GcCardDeviceIdSize = 0x10;
|
||||||
|
public const int GcDeviceCertificateSize = 0x200;
|
||||||
|
public const int GcCardImageHashSize = 0x20;
|
||||||
|
|
||||||
|
public const int GcChallengeCardExistenceResponseSize = 0x58;
|
||||||
|
public const int GcChallengeCardExistenceSeedSize = 0xF;
|
||||||
|
public const int GcChallengeCardExistenceValueSize = 0x10;
|
||||||
|
|
||||||
|
public const int GcMmcCmd60DataSize = 0x40;
|
||||||
|
|
||||||
|
public const int GcAsicFirmwareSize = 1024 * 30; // 30 KiB
|
||||||
|
|
||||||
|
public const int GcAsicSerialNumberLength = 0x10;
|
||||||
|
|
||||||
|
public const int GcRandomValueSize = 32;
|
||||||
|
public const int GcRandomValueForKeyUpdateSocSize = 31;
|
||||||
|
public const int GcRsaOaepSeedSize = 32;
|
||||||
|
|
||||||
|
public const int GcAesBlockLength = Aes.BlockSize;
|
||||||
|
|
||||||
|
public const int GcRsaKeyLength = Rsa.ModulusSize2048Pss;
|
||||||
|
public const int GcRsaPublicExponentLength = Rsa.MaximumExponentSize2048Pss;
|
||||||
|
public const int GcAesKeyLength = Aes.KeySize128;
|
||||||
public const int GcAesCbcIvLength = Aes.KeySize128;
|
public const int GcAesCbcIvLength = Aes.KeySize128;
|
||||||
|
public const int GcHmacKeyLength = 0x20;
|
||||||
|
public const int GcCvConstLength = 0x10;
|
||||||
|
public const int GcTitleKeyKekIndexMax = 0x10;
|
||||||
|
public const int GcSha256HashLength = Sha256.DigestSize;
|
||||||
|
|
||||||
|
public const int GcSendCommandMaxCount = 3;
|
||||||
|
|
||||||
|
public const byte GcPaddingU8 = 0xFF;
|
||||||
|
public const int GcCertificateSize = 0x400;
|
||||||
|
public const int GcSocModulusOffset = 0x130;
|
||||||
|
public const int GcCertificateSetSize = GcCertificateSize + GcAsicSerialNumberLength + GcRsaKeyLength + GcRsaPublicExponentLength;
|
||||||
|
|
||||||
public const long UnusedAreaSizeBase = 1024 * 1024 * 72; // 72 MiB
|
public const long UnusedAreaSizeBase = 1024 * 1024 * 72; // 72 MiB
|
||||||
public const long MemorySizeBase = 1024 * 1024 * 1024; // 1 GiB
|
public const long MemorySizeBase = 1024 * 1024 * 1024; // 1 GiB
|
||||||
public const long AvailableSizeBase = MemorySizeBase - UnusedAreaSizeBase;
|
public const long AvailableSizeBase = MemorySizeBase - UnusedAreaSizeBase;
|
||||||
|
|
||||||
|
public const int Cmd60DefaultTimeOutMilliSeconds = 3500;
|
||||||
|
public const int EraseTimeOutMilliSeconds = 10 * 1000;
|
||||||
}
|
}
|
|
@ -35,4 +35,5 @@ public interface IGcApi
|
||||||
void UnregisterDetectionEventCallback();
|
void UnregisterDetectionEventCallback();
|
||||||
Result GetCardHeader(Span<byte> destBuffer);
|
Result GetCardHeader(Span<byte> destBuffer);
|
||||||
Result GetErrorInfo(out GameCardErrorReportInfo outErrorReportInfo);
|
Result GetErrorInfo(out GameCardErrorReportInfo outErrorReportInfo);
|
||||||
|
Result GetAsicCertificate(out GameCardAsicCertificateSet outCertificateSet);
|
||||||
}
|
}
|
|
@ -768,6 +768,17 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
bytesWritten = Unsafe.SizeOf<DevCardParameter>();
|
bytesWritten = Unsafe.SizeOf<DevCardParameter>();
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
case GameCardManagerOperationIdValue.GetGameCardAsicCertificate:
|
||||||
|
{
|
||||||
|
if (buffer.Size < Unsafe.SizeOf<GameCardAsicCertificateSet>())
|
||||||
|
return ResultFs.InvalidArgument.Log();
|
||||||
|
|
||||||
|
res = GetGameCardAsicCertificate(out buffer.As<GameCardAsicCertificateSet>());
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
bytesWritten = Unsafe.SizeOf<GameCardAsicCertificateSet>();
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ResultFs.InvalidArgument.Log();
|
return ResultFs.InvalidArgument.Log();
|
||||||
|
@ -1042,6 +1053,16 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Result GetGameCardAsicCertificate(out GameCardAsicCertificateSet outCertificateSet)
|
||||||
|
{
|
||||||
|
UnsafeHelpers.SkipParamInit(out outCertificateSet);
|
||||||
|
|
||||||
|
Result res = InitializeGcLibrary();
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
return _gc.GetAsicCertificate(out outCertificateSet).Ret();
|
||||||
|
}
|
||||||
|
|
||||||
public Result AcquireReadLock(ref SharedLock<ReaderWriterLock> outLock, GameCardHandle handle)
|
public Result AcquireReadLock(ref SharedLock<ReaderWriterLock> outLock, GameCardHandle handle)
|
||||||
{
|
{
|
||||||
using (var readLock = new SharedLock<ReaderWriterLock>(_rwLock))
|
using (var readLock = new SharedLock<ReaderWriterLock>(_rwLock))
|
||||||
|
|
|
@ -19,7 +19,8 @@ public enum GameCardManagerOperationIdValue
|
||||||
ReadParamDirectly = 11,
|
ReadParamDirectly = 11,
|
||||||
WriteToGameCardDirectly = 12,
|
WriteToGameCardDirectly = 12,
|
||||||
ForceErase = 13,
|
ForceErase = 13,
|
||||||
SimulateDetectionEventSignaled = 14
|
SimulateDetectionEventSignaled = 14,
|
||||||
|
GetGameCardAsicCertificate = 15
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -87,6 +87,24 @@ public class TypeLayoutTests
|
||||||
Assert.Equal(0, GetOffset(in s, in s.Reserved));
|
Assert.Equal(0, GetOffset(in s, in s.Reserved));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public static void GameCardAsicCertificateSet_Layout()
|
||||||
|
{
|
||||||
|
var s = new GameCardAsicCertificateSet();
|
||||||
|
|
||||||
|
Assert.Equal(Values.GcCertificateSetSize, Unsafe.SizeOf<GameCardAsicCertificateSet>());
|
||||||
|
|
||||||
|
Assert.Equal(0x000, GetOffset(in s, in s.Certificate));
|
||||||
|
Assert.Equal(0x400, GetOffset(in s, in s.SerialNumber));
|
||||||
|
Assert.Equal(0x410, GetOffset(in s, in s.PublicKeyModulus));
|
||||||
|
Assert.Equal(0x510, GetOffset(in s, in s.PublicKeyExponent));
|
||||||
|
|
||||||
|
Assert.Equal(Values.GcCertificateSize, s.Certificate.Length);
|
||||||
|
Assert.Equal(Values.GcAsicSerialNumberLength, s.SerialNumber.Length);
|
||||||
|
Assert.Equal(Values.GcRsaKeyLength, s.PublicKeyModulus.Length);
|
||||||
|
Assert.Equal(Values.GcRsaPublicExponentLength, s.PublicKeyExponent.Length);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public static void CardInitialDataPayload_Layout()
|
public static void CardInitialDataPayload_Layout()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue