Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split out derived device keys into separate prod/dev groups #265

Merged
merged 1 commit into from
Nov 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions build/CodeGen/Stage2/KeysCodeGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ namespace LibHacBuild.CodeGen.Stage2;

public static class KeysCodeGen
{
private static string InputMainKeyFileName = "IncludedKeys.txt";
private static string GeneratedFilePath = "LibHac/Common/Keys/DefaultKeySet.Generated.cs";
private const string InputMainKeyFileName = "IncludedKeys.txt";
private const string GeneratedFilePath = "LibHac/Common/Keys/DefaultKeySet.Generated.cs";

public static void Run()
{
Expand Down Expand Up @@ -45,6 +45,8 @@ private static string BuildDefaultKeySetFile(KeySet keySet)
BuildArray(sb, "DerivedKeysDev", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.DerivedKeysDev));
BuildArray(sb, "DerivedKeysProd", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.DerivedKeysProd));
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, "RsaSigningKeysProd", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.RsaSigningKeysProd));
BuildArray(sb, "RsaKeys", SpanHelpers.AsReadOnlyByteSpan(in keySet.KeyStruct.RsaKeys));
Expand Down
2 changes: 2 additions & 0 deletions src/LibHac/Common/Keys/DefaultKeySet.Empty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ internal static partial class DefaultKeySet
private static ReadOnlySpan<byte> DerivedKeysDev => new byte[] { };
private static ReadOnlySpan<byte> DerivedKeysProd => 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> RsaSigningKeysProd => new byte[] { };
private static ReadOnlySpan<byte> RsaKeys => new byte[] { };
Expand Down
34 changes: 22 additions & 12 deletions src/LibHac/Common/Keys/DefaultKeySet.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Type = LibHac.Common.Keys.KeyInfo.KeyType;

namespace LibHac.Common.Keys;
Expand All @@ -16,59 +15,70 @@ public static KeySet CreateDefaultKeySet()
var keySet = new KeySet();

// 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>())
{
keySet.KeyStruct.RootKeysDev = MemoryMarshal.Cast<byte, RootKeys>(RootKeysDev)[0];
keySet.KeyStruct.RootKeysDev = SpanHelpers.AsReadOnlyStruct<RootKeys>(RootKeysDev);
}

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>())
{
keySet.KeyStruct.KeySeeds = MemoryMarshal.Cast<byte, KeySeeds>(KeySeeds)[0];
keySet.KeyStruct.KeySeeds = SpanHelpers.AsReadOnlyStruct<KeySeeds>(KeySeeds);
}

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>())
{
keySet.KeyStruct.StoredKeysProd = MemoryMarshal.Cast<byte, StoredKeys>(StoredKeysProd)[0];
keySet.KeyStruct.StoredKeysProd = SpanHelpers.AsReadOnlyStruct<StoredKeys>(StoredKeysProd);
}

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>())
{
keySet.KeyStruct.DerivedKeysProd = MemoryMarshal.Cast<byte, DerivedKeys>(DerivedKeysProd)[0];
keySet.KeyStruct.DerivedKeysProd = SpanHelpers.AsReadOnlyStruct<DerivedKeys>(DerivedKeysProd);
}

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>())
{
keySet.KeyStruct.RsaSigningKeysDev = MemoryMarshal.Cast<byte, RsaSigningKeys>(RsaSigningKeysDev)[0];
keySet.KeyStruct.RsaSigningKeysDev = SpanHelpers.AsReadOnlyStruct<RsaSigningKeys>(RsaSigningKeysDev);
}

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>())
{
keySet.KeyStruct.RsaKeys = MemoryMarshal.Cast<byte, RsaKeys>(RsaKeys)[0];
keySet.KeyStruct.RsaKeys = SpanHelpers.AsReadOnlyStruct<RsaKeys>(RsaKeys);
}

return keySet;
Expand Down
28 changes: 18 additions & 10 deletions src/LibHac/Common/Keys/KeySet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public enum Mode
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 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 RsaKeys RsaKeys => ref _keys.RsaKeys;

Expand Down Expand Up @@ -94,17 +95,18 @@ public enum Mode

public ref AesKey SecureBootKey => ref _keys.DeviceKeys.SecureBootKey;
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 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.
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> AcidSigningKeys => RsaSigningKeys.AcidSigningKeys.Items;
Expand Down Expand Up @@ -269,6 +271,8 @@ public struct AllKeys
public DerivedKeys DerivedKeysDev;
public DerivedKeys DerivedKeysProd;
public DeviceKeys DeviceKeys;
public DerivedDeviceKeys DerivedDeviceKeysDev;
public DerivedDeviceKeys DerivedDeviceKeysProd;
public RsaSigningKeys RsaSigningKeysDev;
public RsaSigningKeys RsaSigningKeysProd;
public RsaKeys RsaKeys;
Expand Down Expand Up @@ -354,14 +358,18 @@ public struct DeviceKeys
{
public AesKey SecureBootKey;
public AesKey TsecKey;
public AesKey SdCardEncryptionSeed;
public Array32<EncryptedKeyBlob> EncryptedKeyBlobs;
}

public struct DerivedDeviceKeys
{
public Array32<AesKey> KeyBlobKeys;
public Array32<AesKey> KeyBlobMacKeys;
public Array32<EncryptedKeyBlob> EncryptedKeyBlobs;
public AesKey DeviceKey;
public Array4<AesXtsKey> BisKeys;
public Array2<AesKey> DeviceUniqueSaveMacKeys;
public AesKey SeedUniqueSaveMacKey;
public AesKey SdCardEncryptionSeed;
public Array3<AesXtsKey> SdCardEncryptionKeys;
}

Expand Down