Split out derived device keys into separate prod/dev groups

This fixes an issue where reading certain device keys/seeds would result in dev derived keys instead of prod derived keys
This commit is contained in:
Alex Barney 2022-11-22 23:45:14 -07:00
parent eccd91bc15
commit fe8699e8c4
4 changed files with 46 additions and 24 deletions

View file

@ -11,8 +11,8 @@ namespace LibHacBuild.CodeGen.Stage2;
public static class KeysCodeGen public static class KeysCodeGen
{ {
private static string InputMainKeyFileName = "IncludedKeys.txt"; private const string InputMainKeyFileName = "IncludedKeys.txt";
private static string GeneratedFilePath = "LibHac/Common/Keys/DefaultKeySet.Generated.cs"; private const string GeneratedFilePath = "LibHac/Common/Keys/DefaultKeySet.Generated.cs";
public static void Run() public static void Run()
{ {
@ -45,6 +45,8 @@ public static class KeysCodeGen
BuildArray(sb, "DerivedKeysDev", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.DerivedKeysDev)); BuildArray(sb, "DerivedKeysDev", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.DerivedKeysDev));
BuildArray(sb, "DerivedKeysProd", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.DerivedKeysProd)); BuildArray(sb, "DerivedKeysProd", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.DerivedKeysProd));
BuildArray(sb, "DeviceKeys", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.DeviceKeys)); BuildArray(sb, "DeviceKeys", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.DeviceKeys));
BuildArray(sb, "DerivedDeviceKeysDev", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.DerivedDeviceKeysDev));
BuildArray(sb, "DerivedDeviceKeysProd", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.DerivedDeviceKeysProd));
BuildArray(sb, "RsaSigningKeysDev", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.RsaSigningKeysDev)); BuildArray(sb, "RsaSigningKeysDev", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.RsaSigningKeysDev));
BuildArray(sb, "RsaSigningKeysProd", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.RsaSigningKeysProd)); BuildArray(sb, "RsaSigningKeysProd", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.RsaSigningKeysProd));
BuildArray(sb, "RsaKeys", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.RsaKeys)); BuildArray(sb, "RsaKeys", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.RsaKeys));

View file

@ -12,6 +12,8 @@ internal static partial class DefaultKeySet
private static ReadOnlySpan<byte> DerivedKeysDev => new byte[] { }; private static ReadOnlySpan<byte> DerivedKeysDev => new byte[] { };
private static ReadOnlySpan<byte> DerivedKeysProd => new byte[] { }; private static ReadOnlySpan<byte> DerivedKeysProd => new byte[] { };
private static ReadOnlySpan<byte> DeviceKeys => new byte[] { }; private static ReadOnlySpan<byte> DeviceKeys => new byte[] { };
private static ReadOnlySpan<byte> DerivedDeviceKeysDev => new byte[] { };
private static ReadOnlySpan<byte> DerivedDeviceKeysProd => new byte[] { };
private static ReadOnlySpan<byte> RsaSigningKeysDev => new byte[] { }; private static ReadOnlySpan<byte> RsaSigningKeysDev => new byte[] { };
private static ReadOnlySpan<byte> RsaSigningKeysProd => new byte[] { }; private static ReadOnlySpan<byte> RsaSigningKeysProd => new byte[] { };
private static ReadOnlySpan<byte> RsaKeys => new byte[] { }; private static ReadOnlySpan<byte> RsaKeys => new byte[] { };

View file

@ -1,6 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Type = LibHac.Common.Keys.KeyInfo.KeyType; using Type = LibHac.Common.Keys.KeyInfo.KeyType;
namespace LibHac.Common.Keys; namespace LibHac.Common.Keys;
@ -16,59 +15,70 @@ internal static partial class DefaultKeySet
var keySet = new KeySet(); var keySet = new KeySet();
// Fill the key set with any key structs included in the library. // Fill the key set with any key structs included in the library.
// This is split into multiple parts so the binary size isn't increased when providing only some keys.
if (RootKeysDev.Length == Unsafe.SizeOf<RootKeys>()) if (RootKeysDev.Length == Unsafe.SizeOf<RootKeys>())
{ {
keySet.KeyStruct.RootKeysDev = MemoryMarshal.Cast<byte, RootKeys>(RootKeysDev)[0]; keySet.KeyStruct.RootKeysDev = SpanHelpers.AsReadOnlyStruct<RootKeys>(RootKeysDev);
} }
if (RootKeysProd.Length == Unsafe.SizeOf<RootKeys>()) if (RootKeysProd.Length == Unsafe.SizeOf<RootKeys>())
{ {
keySet.KeyStruct.RootKeysProd = MemoryMarshal.Cast<byte, RootKeys>(RootKeysProd)[0]; keySet.KeyStruct.RootKeysProd = SpanHelpers.AsReadOnlyStruct<RootKeys>(RootKeysProd);
} }
if (KeySeeds.Length == Unsafe.SizeOf<KeySeeds>()) if (KeySeeds.Length == Unsafe.SizeOf<KeySeeds>())
{ {
keySet.KeyStruct.KeySeeds = MemoryMarshal.Cast<byte, KeySeeds>(KeySeeds)[0]; keySet.KeyStruct.KeySeeds = SpanHelpers.AsReadOnlyStruct<KeySeeds>(KeySeeds);
} }
if (StoredKeysDev.Length == Unsafe.SizeOf<StoredKeys>()) if (StoredKeysDev.Length == Unsafe.SizeOf<StoredKeys>())
{ {
keySet.KeyStruct.StoredKeysDev = MemoryMarshal.Cast<byte, StoredKeys>(StoredKeysDev)[0]; keySet.KeyStruct.StoredKeysDev = SpanHelpers.AsReadOnlyStruct<StoredKeys>(StoredKeysDev);
} }
if (StoredKeysProd.Length == Unsafe.SizeOf<StoredKeys>()) if (StoredKeysProd.Length == Unsafe.SizeOf<StoredKeys>())
{ {
keySet.KeyStruct.StoredKeysProd = MemoryMarshal.Cast<byte, StoredKeys>(StoredKeysProd)[0]; keySet.KeyStruct.StoredKeysProd = SpanHelpers.AsReadOnlyStruct<StoredKeys>(StoredKeysProd);
} }
if (DerivedKeysDev.Length == Unsafe.SizeOf<DerivedKeys>()) if (DerivedKeysDev.Length == Unsafe.SizeOf<DerivedKeys>())
{ {
keySet.KeyStruct.DerivedKeysDev = MemoryMarshal.Cast<byte, DerivedKeys>(DerivedKeysDev)[0]; keySet.KeyStruct.DerivedKeysDev = SpanHelpers.AsReadOnlyStruct<DerivedKeys>(DerivedKeysDev);
} }
if (DerivedKeysProd.Length == Unsafe.SizeOf<DerivedKeys>()) if (DerivedKeysProd.Length == Unsafe.SizeOf<DerivedKeys>())
{ {
keySet.KeyStruct.DerivedKeysProd = MemoryMarshal.Cast<byte, DerivedKeys>(DerivedKeysProd)[0]; keySet.KeyStruct.DerivedKeysProd = SpanHelpers.AsReadOnlyStruct<DerivedKeys>(DerivedKeysProd);
} }
if (DeviceKeys.Length == Unsafe.SizeOf<DeviceKeys>()) if (DeviceKeys.Length == Unsafe.SizeOf<DeviceKeys>())
{ {
keySet.KeyStruct.DeviceKeys = MemoryMarshal.Cast<byte, DeviceKeys>(DeviceKeys)[0]; keySet.KeyStruct.DeviceKeys = SpanHelpers.AsReadOnlyStruct<DeviceKeys>(DeviceKeys);
}
if (DerivedDeviceKeysDev.Length == Unsafe.SizeOf<DerivedDeviceKeys>())
{
keySet.KeyStruct.DerivedDeviceKeysDev = SpanHelpers.AsReadOnlyStruct<DerivedDeviceKeys>(DerivedDeviceKeysDev);
}
if (DerivedDeviceKeysProd.Length == Unsafe.SizeOf<DerivedDeviceKeys>())
{
keySet.KeyStruct.DerivedDeviceKeysProd = SpanHelpers.AsReadOnlyStruct<DerivedDeviceKeys>(DerivedDeviceKeysProd);
} }
if (RsaSigningKeysDev.Length == Unsafe.SizeOf<RsaSigningKeys>()) if (RsaSigningKeysDev.Length == Unsafe.SizeOf<RsaSigningKeys>())
{ {
keySet.KeyStruct.RsaSigningKeysDev = MemoryMarshal.Cast<byte, RsaSigningKeys>(RsaSigningKeysDev)[0]; keySet.KeyStruct.RsaSigningKeysDev = SpanHelpers.AsReadOnlyStruct<RsaSigningKeys>(RsaSigningKeysDev);
} }
if (RsaSigningKeysProd.Length == Unsafe.SizeOf<RsaSigningKeys>()) if (RsaSigningKeysProd.Length == Unsafe.SizeOf<RsaSigningKeys>())
{ {
keySet.KeyStruct.RsaSigningKeysProd = MemoryMarshal.Cast<byte, RsaSigningKeys>(RsaSigningKeysProd)[0]; keySet.KeyStruct.RsaSigningKeysProd = SpanHelpers.AsReadOnlyStruct<RsaSigningKeys>(RsaSigningKeysProd);
} }
if (RsaKeys.Length == Unsafe.SizeOf<RsaKeys>()) if (RsaKeys.Length == Unsafe.SizeOf<RsaKeys>())
{ {
keySet.KeyStruct.RsaKeys = MemoryMarshal.Cast<byte, RsaKeys>(RsaKeys)[0]; keySet.KeyStruct.RsaKeys = SpanHelpers.AsReadOnlyStruct<RsaKeys>(RsaKeys);
} }
return keySet; return keySet;

View file

@ -33,6 +33,7 @@ public class KeySet
private ref RootKeys RootKeys => ref _mode == Mode.Dev ? ref _keys.RootKeysDev : ref _keys.RootKeysProd; private ref RootKeys RootKeys => ref _mode == Mode.Dev ? ref _keys.RootKeysDev : ref _keys.RootKeysProd;
private ref StoredKeys StoredKeys => ref _mode == Mode.Dev ? ref _keys.StoredKeysDev : ref _keys.StoredKeysProd; private ref StoredKeys StoredKeys => ref _mode == Mode.Dev ? ref _keys.StoredKeysDev : ref _keys.StoredKeysProd;
private ref DerivedKeys DerivedKeys => ref _mode == Mode.Dev ? ref _keys.DerivedKeysDev : ref _keys.DerivedKeysProd; private ref DerivedKeys DerivedKeys => ref _mode == Mode.Dev ? ref _keys.DerivedKeysDev : ref _keys.DerivedKeysProd;
private ref DerivedDeviceKeys DerivedDeviceKeys => ref _mode == Mode.Dev ? ref _keys.DerivedDeviceKeysDev : ref _keys.DerivedDeviceKeysProd;
private ref RsaSigningKeys RsaSigningKeys => ref _mode == Mode.Dev ? ref _keys.RsaSigningKeysDev : ref _keys.RsaSigningKeysProd; private ref RsaSigningKeys RsaSigningKeys => ref _mode == Mode.Dev ? ref _keys.RsaSigningKeysDev : ref _keys.RsaSigningKeysProd;
private ref RsaKeys RsaKeys => ref _keys.RsaKeys; private ref RsaKeys RsaKeys => ref _keys.RsaKeys;
@ -94,17 +95,18 @@ public class KeySet
public ref AesKey SecureBootKey => ref _keys.DeviceKeys.SecureBootKey; public ref AesKey SecureBootKey => ref _keys.DeviceKeys.SecureBootKey;
public ref AesKey TsecKey => ref _keys.DeviceKeys.TsecKey; public ref AesKey TsecKey => ref _keys.DeviceKeys.TsecKey;
public Span<AesKey> KeyBlobKeys => _keys.DeviceKeys.KeyBlobKeys.Items;
public Span<AesKey> KeyBlobMacKeys => _keys.DeviceKeys.KeyBlobMacKeys.Items;
public Span<EncryptedKeyBlob> EncryptedKeyBlobs => _keys.DeviceKeys.EncryptedKeyBlobs.Items;
public ref AesKey DeviceKey => ref _keys.DeviceKeys.DeviceKey;
public Span<AesXtsKey> BisKeys => _keys.DeviceKeys.BisKeys.Items;
public Span<AesKey> DeviceUniqueSaveMacKeys => _keys.DeviceKeys.DeviceUniqueSaveMacKeys.Items;
public ref AesKey SeedUniqueSaveMacKey => ref _keys.DeviceKeys.SeedUniqueSaveMacKey;
public ref AesKey SdCardEncryptionSeed => ref _keys.DeviceKeys.SdCardEncryptionSeed; public ref AesKey SdCardEncryptionSeed => ref _keys.DeviceKeys.SdCardEncryptionSeed;
public Span<EncryptedKeyBlob> EncryptedKeyBlobs => _keys.DeviceKeys.EncryptedKeyBlobs.Items;
public Span<AesKey> KeyBlobKeys => DerivedDeviceKeys.KeyBlobKeys.Items;
public Span<AesKey> KeyBlobMacKeys => DerivedDeviceKeys.KeyBlobMacKeys.Items;
public ref AesKey DeviceKey => ref DerivedDeviceKeys.DeviceKey;
public Span<AesXtsKey> BisKeys => DerivedDeviceKeys.BisKeys.Items;
public Span<AesKey> DeviceUniqueSaveMacKeys => DerivedDeviceKeys.DeviceUniqueSaveMacKeys.Items;
public ref AesKey SeedUniqueSaveMacKey => ref DerivedDeviceKeys.SeedUniqueSaveMacKey;
// Todo: Make a separate type? Not actually an AES-XTS key, but it's still the same shape. // Todo: Make a separate type? Not actually an AES-XTS key, but it's still the same shape.
public Span<AesXtsKey> SdCardEncryptionKeys => _keys.DeviceKeys.SdCardEncryptionKeys.Items; public Span<AesXtsKey> SdCardEncryptionKeys => DerivedDeviceKeys.SdCardEncryptionKeys.Items;
public Span<RsaKey> NcaHeaderSigningKeys => RsaSigningKeys.NcaHeaderSigningKeys.Items; public Span<RsaKey> NcaHeaderSigningKeys => RsaSigningKeys.NcaHeaderSigningKeys.Items;
public Span<RsaKey> AcidSigningKeys => RsaSigningKeys.AcidSigningKeys.Items; public Span<RsaKey> AcidSigningKeys => RsaSigningKeys.AcidSigningKeys.Items;
@ -269,6 +271,8 @@ public struct AllKeys
public DerivedKeys DerivedKeysDev; public DerivedKeys DerivedKeysDev;
public DerivedKeys DerivedKeysProd; public DerivedKeys DerivedKeysProd;
public DeviceKeys DeviceKeys; public DeviceKeys DeviceKeys;
public DerivedDeviceKeys DerivedDeviceKeysDev;
public DerivedDeviceKeys DerivedDeviceKeysProd;
public RsaSigningKeys RsaSigningKeysDev; public RsaSigningKeys RsaSigningKeysDev;
public RsaSigningKeys RsaSigningKeysProd; public RsaSigningKeys RsaSigningKeysProd;
public RsaKeys RsaKeys; public RsaKeys RsaKeys;
@ -354,14 +358,18 @@ public struct DeviceKeys
{ {
public AesKey SecureBootKey; public AesKey SecureBootKey;
public AesKey TsecKey; public AesKey TsecKey;
public AesKey SdCardEncryptionSeed;
public Array32<EncryptedKeyBlob> EncryptedKeyBlobs;
}
public struct DerivedDeviceKeys
{
public Array32<AesKey> KeyBlobKeys; public Array32<AesKey> KeyBlobKeys;
public Array32<AesKey> KeyBlobMacKeys; public Array32<AesKey> KeyBlobMacKeys;
public Array32<EncryptedKeyBlob> EncryptedKeyBlobs;
public AesKey DeviceKey; public AesKey DeviceKey;
public Array4<AesXtsKey> BisKeys; public Array4<AesXtsKey> BisKeys;
public Array2<AesKey> DeviceUniqueSaveMacKeys; public Array2<AesKey> DeviceUniqueSaveMacKeys;
public AesKey SeedUniqueSaveMacKey; public AesKey SeedUniqueSaveMacKey;
public AesKey SdCardEncryptionSeed;
public Array3<AesXtsKey> SdCardEncryptionKeys; public Array3<AesXtsKey> SdCardEncryptionKeys;
} }