mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add a function to calculate a pk11 mac and use it in hactoolnet
This commit is contained in:
parent
bb13864030
commit
a1439a2647
5 changed files with 71 additions and 5 deletions
|
@ -1935,3 +1935,10 @@ Module,DescriptionStart,DescriptionEnd,Flags,Namespace,Name,Summary
|
||||||
428,1041,,,,InvalidPackage1SectionSize,
|
428,1041,,,,InvalidPackage1SectionSize,
|
||||||
428,1042,,,,InvalidPackage1MarikoBodySize,
|
428,1042,,,,InvalidPackage1MarikoBodySize,
|
||||||
428,1043,,,,InvalidPackage1Pk11Size,
|
428,1043,,,,InvalidPackage1Pk11Size,
|
||||||
|
|
||||||
|
428,2000,2199,,,PreconditionViolation,
|
||||||
|
428,2001,2019,,,UnsupportedOperation,
|
||||||
|
428,2002,,,,UnsupportedCalculateMacForPackage1,The package1 type doesn't support calculating a MAC over its pk11. Only modern Erista package1s support this.
|
||||||
|
|
||||||
|
428,2050,2069,,,KeyNotFound,
|
||||||
|
428,2051,,,,Package1MacKeyNotFound,
|
|
|
@ -6,10 +6,12 @@ using System.Runtime.InteropServices;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Common.FixedArrays;
|
using LibHac.Common.FixedArrays;
|
||||||
using LibHac.Common.Keys;
|
using LibHac.Common.Keys;
|
||||||
|
using LibHac.Crypto;
|
||||||
using LibHac.Diag;
|
using LibHac.Diag;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
using LibHac.Util;
|
using LibHac.Util;
|
||||||
|
using AesKey = LibHac.Crypto.AesKey;
|
||||||
|
|
||||||
namespace LibHac.Boot;
|
namespace LibHac.Boot;
|
||||||
|
|
||||||
|
@ -153,6 +155,35 @@ public class Package1
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the MAC for a modern Erista pk11.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="macBuffer">The buffer where the generated MAC will be placed. Must be at least 16 bytes long.</param>
|
||||||
|
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
||||||
|
/// <see cref="ResultLibHac.UnsupportedCalculateMacForPackage1"/>: The package1 type does not support calculating
|
||||||
|
/// a MAC over its pk11.<br/>
|
||||||
|
/// <see cref="ResultLibHac.Package1MacKeyNotFound"/>: The key used to calculate the MAC was not found
|
||||||
|
/// in the <see cref="KeySet"/>.</returns>
|
||||||
|
public Result CalculateModernEristaMac(Span<byte> macBuffer)
|
||||||
|
{
|
||||||
|
if (IsMariko || !IsModern)
|
||||||
|
return ResultLibHac.UnsupportedCalculateMacForPackage1.Log();
|
||||||
|
|
||||||
|
AesKey macKey = KeySet.Package1MacKeys[KeyRevision];
|
||||||
|
if (macKey.IsZeros())
|
||||||
|
return ResultLibHac.Package1MacKeyNotFound.Log();
|
||||||
|
|
||||||
|
// Todo: Use a smaller buffer instead of reading the entire thing in at once.
|
||||||
|
byte[] macTarget = new byte[Pk11Size + 0x20];
|
||||||
|
|
||||||
|
Result res = _bodyStorage.Read(0x7000 - 0x20, macTarget);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
Aes.CalculateCmac(macBuffer, macTarget, macKey);
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read the encrypted section of a Mariko Package1 and try to decrypt it.
|
/// Read the encrypted section of a Mariko Package1 and try to decrypt it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -92,4 +92,16 @@ public static class ResultLibHac
|
||||||
public static Result.Base InvalidPackage1MarikoBodySize => new Result.Base(ModuleLibHac, 1042);
|
public static Result.Base InvalidPackage1MarikoBodySize => new Result.Base(ModuleLibHac, 1042);
|
||||||
/// <summary>Error code: 2428-1043; Inner value: 0x827ac</summary>
|
/// <summary>Error code: 2428-1043; Inner value: 0x827ac</summary>
|
||||||
public static Result.Base InvalidPackage1Pk11Size => new Result.Base(ModuleLibHac, 1043);
|
public static Result.Base InvalidPackage1Pk11Size => new Result.Base(ModuleLibHac, 1043);
|
||||||
|
|
||||||
|
/// <summary>Error code: 2428-2000; Range: 2000-2199; Inner value: 0xfa1ac</summary>
|
||||||
|
public static Result.Base PreconditionViolation { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleLibHac, 2000, 2199); }
|
||||||
|
/// <summary>Error code: 2428-2001; Range: 2001-2019; Inner value: 0xfa3ac</summary>
|
||||||
|
public static Result.Base UnsupportedOperation { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleLibHac, 2001, 2019); }
|
||||||
|
/// <summary>The package1 type doesn't support calculating a MAC over its pk11. Only modern Erista package1s support this.<br/>Error code: 2428-2002; Inner value: 0xfa5ac</summary>
|
||||||
|
public static Result.Base UnsupportedCalculateMacForPackage1 => new Result.Base(ModuleLibHac, 2002);
|
||||||
|
|
||||||
|
/// <summary>Error code: 2428-2050; Range: 2050-2069; Inner value: 0x1005ac</summary>
|
||||||
|
public static Result.Base KeyNotFound { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleLibHac, 2050, 2069); }
|
||||||
|
/// <summary>Error code: 2428-2051; Inner value: 0x1007ac</summary>
|
||||||
|
public static Result.Base Package1MacKeyNotFound => new Result.Base(ModuleLibHac, 2051);
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using System.IO;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using LibHac;
|
using LibHac;
|
||||||
|
@ -82,7 +83,22 @@ internal static class ProcessPackage
|
||||||
|
|
||||||
if (!package1.IsMariko && package1.IsModern)
|
if (!package1.IsMariko && package1.IsModern)
|
||||||
{
|
{
|
||||||
PrintItem(sb, colLen, " PK11 MAC:", package1.Pk11Mac.ItemsRo.ToArray());
|
string validity = "";
|
||||||
|
|
||||||
|
Span<byte> mac = stackalloc byte[0x10];
|
||||||
|
Result res = package1.CalculateModernEristaMac(mac);
|
||||||
|
|
||||||
|
if (res.IsFailure())
|
||||||
|
{
|
||||||
|
if (!ResultLibHac.Package1MacKeyNotFound.Includes(res))
|
||||||
|
res.ThrowIfFailure();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
validity = mac.SequenceEqual(package1.Pk11Mac) ? " (Valid)" : " (Invalid)";
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintItem(sb, colLen, $" PK11 MAC:{validity}", package1.Pk11Mac.ItemsRo.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package1.IsDecrypted)
|
if (package1.IsDecrypted)
|
||||||
|
@ -91,7 +107,7 @@ internal static class ProcessPackage
|
||||||
|
|
||||||
if (!package1.IsMariko)
|
if (!package1.IsMariko)
|
||||||
{
|
{
|
||||||
PrintItem(sb, colLen, " Key Revision:", $"{package1.KeyRevision:x2} ({Utilities.GetKeyRevisionSummary(package1.KeyRevision)})");
|
PrintItem(sb, colLen, " Key Revision:", $"{package1.KeyRevision:x2}");
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintItem(sb, colLen, " PK11 Size:", $"{package1.Pk11Size:x8}");
|
PrintItem(sb, colLen, " PK11 Size:", $"{package1.Pk11Size:x8}");
|
||||||
|
|
Loading…
Reference in a new issue