Add support for decrypting personalized title keys using eticket_rsa_keypair.

This commit is contained in:
Steveice10 2022-12-02 20:51:23 -08:00 committed by Alex Barney
parent a1439a2647
commit 572849b67d
5 changed files with 33 additions and 3 deletions

View file

@ -183,6 +183,7 @@ internal static partial class DefaultKeySet
keys.Add(new KeyInfo(280, Type.CommonRoot, "eticket_rsa_kek", (set, _) => set.ETicketRsaKek)); keys.Add(new KeyInfo(280, Type.CommonRoot, "eticket_rsa_kek", (set, _) => set.ETicketRsaKek));
keys.Add(new KeyInfo(281, Type.CommonRoot, "ssl_rsa_kek", (set, _) => set.SslRsaKek)); keys.Add(new KeyInfo(281, Type.CommonRoot, "ssl_rsa_kek", (set, _) => set.SslRsaKek));
keys.Add(new KeyInfo(282, Type.DeviceDrvd, "eticket_rsa_keypair", (set, _) => set.ETicketRsaKeyPair));
keys.Add(new KeyInfo(290, Type.CommonDrvd, "key_area_key_application", 0, KeyRevisionCount, (set, i) => set.KeyAreaKeys[i][0])); keys.Add(new KeyInfo(290, Type.CommonDrvd, "key_area_key_application", 0, KeyRevisionCount, (set, i) => set.KeyAreaKeys[i][0]));
keys.Add(new KeyInfo(300, Type.CommonDrvd, "key_area_key_ocean", 0, KeyRevisionCount, (set, i) => set.KeyAreaKeys[i][1])); keys.Add(new KeyInfo(300, Type.CommonDrvd, "key_area_key_ocean", 0, KeyRevisionCount, (set, i) => set.KeyAreaKeys[i][1]));

View file

@ -12,7 +12,7 @@ namespace LibHac.Common.Keys;
public static class ExternalKeyReader public static class ExternalKeyReader
{ {
private const int ReadBufferSize = 1024; private const int ReadBufferSize = 2048;
// Contains info from a specific key being read from a file // Contains info from a specific key being read from a file
[DebuggerDisplay("{" + nameof(Name) + "}")] [DebuggerDisplay("{" + nameof(Name) + "}")]

View file

@ -129,7 +129,7 @@ public class KeySet
private RsaSigningKeyParameters _rsaSigningKeyParamsProd; private RsaSigningKeyParameters _rsaSigningKeyParamsProd;
private RsaKeyParameters _rsaKeyParams; private RsaKeyParameters _rsaKeyParams;
public RSAParameters ETicketExtKeyRsa { get; set; } public ref RsaKeyPair ETicketRsaKeyPair => ref DerivedDeviceKeys.ETicketRsaKeyPair;
public Span<RSAParameters> NcaHeaderSigningKeyParams public Span<RSAParameters> NcaHeaderSigningKeyParams
{ {
@ -389,6 +389,7 @@ public struct DerivedDeviceKeys
public Array2<AesKey> DeviceUniqueSaveMacKeys; public Array2<AesKey> DeviceUniqueSaveMacKeys;
public AesKey SeedUniqueSaveMacKey; public AesKey SeedUniqueSaveMacKey;
public Array3<AesXtsKey> SdCardEncryptionKeys; public Array3<AesXtsKey> SdCardEncryptionKeys;
public RsaKeyPair ETicketRsaKeyPair;
} }
public struct RsaSigningKeys public struct RsaSigningKeys

View file

@ -132,4 +132,26 @@ public struct RsaKey
{ {
public Array256<byte> Modulus; public Array256<byte> Modulus;
public Array3<byte> PublicExponent; public Array3<byte> PublicExponent;
}
[StructLayout(LayoutKind.Explicit, Size = Size)]
public struct RsaKeyPair
{
private const int Size = 0x210;
[FieldOffset(0)] private byte _byte;
[FieldOffset(0)] private ulong _ulong;
[FieldOffset(0)] public Array256<byte> PrivateExponent;
[FieldOffset(0x100)] public Array256<byte> Modulus;
[FieldOffset(0x200)] public Array4<byte> PublicExponent;
[FieldOffset(0x204)] public Array12<byte> Reserved;
public Span<byte> Data => SpanHelpers.CreateSpan(ref _byte, Size);
public readonly ReadOnlySpan<byte> DataRo => SpanHelpers.CreateReadOnlySpan(in _byte, Size);
public static implicit operator Span<byte>(in RsaKeyPair value) => Unsafe.AsRef(in value).Data;
public static implicit operator ReadOnlySpan<byte>(in RsaKeyPair value) => value.DataRo;
public readonly override string ToString() => DataRo.ToHexString();
} }

View file

@ -1,7 +1,9 @@
using System; using System;
using System.IO; using System.IO;
using System.Security.Cryptography;
using LibHac.Common; using LibHac.Common;
using LibHac.Common.Keys; using LibHac.Common.Keys;
using LibHac.Crypto;
using LibHac.Tools.Crypto; using LibHac.Tools.Crypto;
using LibHac.Util; using LibHac.Util;
@ -157,7 +159,11 @@ public class Ticket
return commonKey; return commonKey;
} }
return CryptoOld.DecryptRsaOaep(TitleKeyBlock, keySet.ETicketExtKeyRsa); RSAParameters rsaParameters = Rsa.RecoverParameters(
keySet.ETicketRsaKeyPair.Modulus,
keySet.ETicketRsaKeyPair.PublicExponent,
keySet.ETicketRsaKeyPair.PrivateExponent);
return CryptoOld.DecryptRsaOaep(TitleKeyBlock, rsaParameters);
} }
} }