diff --git a/KEYS.md b/KEYS.md index e8aa1be2..ae8035bd 100644 --- a/KEYS.md +++ b/KEYS.md @@ -45,58 +45,61 @@ This template contains the keys needed to derive all the keys used by hactoolnet Fill out the template with the actual keys to get a working keyfile. ``` -master_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -master_key_00 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -master_key_01 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -master_key_02 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -master_key_03 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -master_key_04 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -master_key_05 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +master_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +master_key_00 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +master_key_01 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +master_key_02 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +master_key_03 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +master_key_04 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +master_key_05 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +keyblob_mac_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +keyblob_key_source_00 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +keyblob_key_source_01 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +keyblob_key_source_02 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +keyblob_key_source_03 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +keyblob_key_source_04 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +keyblob_key_source_05 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +package1_key_00 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +package1_key_01 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +package1_key_02 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +package1_key_03 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +package1_key_04 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +package2_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +aes_kek_generation_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +aes_key_generation_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +titlekek_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +key_area_key_application_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +key_area_key_ocean_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +key_area_key_system_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +sd_card_kek_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +sd_card_save_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +sd_card_nca_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +sd_card_custom_storage_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -keyblob_mac_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -keyblob_key_source_00 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -keyblob_key_source_01 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -keyblob_key_source_02 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -keyblob_key_source_03 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -keyblob_key_source_04 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -keyblob_key_source_05 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - -package1_key_00 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -package1_key_01 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -package1_key_02 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -package1_key_03 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -package1_key_04 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - -package2_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - -aes_kek_generation_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -aes_key_generation_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -titlekek_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - -key_area_key_application_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -key_area_key_ocean_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -key_area_key_system_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - -sd_card_kek_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -sd_card_save_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -sd_card_nca_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - -header_kek_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -header_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - -xci_header_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - -retail_specific_aes_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -per_console_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -eticket_rsa_kek = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - -bis_key_source_00 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -bis_key_source_01 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -bis_key_source_02 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -bis_kek_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - -save_mac_kek_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -save_mac_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +header_kek_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +header_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +xci_header_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +retail_specific_aes_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +per_console_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +eticket_rsa_kek = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +bis_key_source_00 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +bis_key_source_01 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +bis_key_source_02 = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +bis_kek_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +save_mac_kek_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +save_mac_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +save_mac_sd_card_kek_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +save_mac_sd_card_key_source = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ``` ### Console-unique keys diff --git a/src/LibHac/Keyset.cs b/src/LibHac/Keyset.cs index 698f7337..39b5538a 100644 --- a/src/LibHac/Keyset.cs +++ b/src/LibHac/Keyset.cs @@ -15,6 +15,8 @@ namespace LibHac /// private const int UsedKeyblobCount = 6; + private const int SdCardKeyIdCount = 3; + public byte[][] KeyblobKeys { get; } = Util.CreateJaggedArray(0x20, 0x10); public byte[][] KeyblobMacKeys { get; } = Util.CreateJaggedArray(0x20, 0x10); public byte[][] EncryptedKeyblobs { get; } = Util.CreateJaggedArray(0x20, 0xB0); @@ -35,11 +37,13 @@ namespace LibHac public byte[] KeyAreaKeyOceanSource { get; } = new byte[0x10]; public byte[] KeyAreaKeySystemSource { get; } = new byte[0x10]; public byte[] SaveMacKekSource { get; } = new byte[0x10]; + public byte[] SaveMacSdCardKekSource { get; } = new byte[0x10]; public byte[] SaveMacKeySource { get; } = new byte[0x10]; + public byte[] SaveMacSdCardKeySource { get; } = new byte[0x10]; public byte[] TitleKekSource { get; } = new byte[0x10]; public byte[] HeaderKekSource { get; } = new byte[0x10]; public byte[] SdCardKekSource { get; } = new byte[0x10]; - public byte[][] SdCardKeySources { get; } = Util.CreateJaggedArray(2, 0x20); + public byte[][] SdCardKeySources { get; } = Util.CreateJaggedArray(SdCardKeyIdCount, 0x20); public byte[] HeaderKeySource { get; } = new byte[0x20]; public byte[] HeaderKey { get; } = new byte[0x20]; public byte[] XciHeaderKey { get; } = new byte[0x10]; @@ -58,9 +62,10 @@ namespace LibHac public byte[] DeviceKey { get; } = new byte[0x10]; public byte[][] BisKeys { get; } = Util.CreateJaggedArray(4, 0x20); public byte[] SaveMacKey { get; } = new byte[0x10]; + public byte[] SaveMacSdCardKey { get; } = new byte[0x10]; public byte[] SdSeed { get; } = new byte[0x10]; - public byte[][] SdCardKeySourcesSpecific { get; } = Util.CreateJaggedArray(2, 0x20); - public byte[][] SdCardKeys { get; } = Util.CreateJaggedArray(2, 0x20); + public byte[][] SdCardKeySourcesSpecific { get; } = Util.CreateJaggedArray(SdCardKeyIdCount, 0x20); + public byte[][] SdCardKeys { get; } = Util.CreateJaggedArray(SdCardKeyIdCount, 0x20); public RSAParameters EticketExtKeyRsa { get; set; } @@ -336,7 +341,7 @@ namespace LibHac var sdKek = new byte[0x10]; Crypto.GenerateKek(MasterKeys[0], SdCardKekSource, sdKek, AesKekGenerationSource, AesKeyGenerationSource); - for (int k = 0; k < SdCardKeySources.Length; k++) + for (int k = 0; k < SdCardKeyIdCount; k++) { for (int i = 0; i < 0x20; i++) { @@ -344,10 +349,24 @@ namespace LibHac } } - for (int k = 0; k < SdCardKeySourcesSpecific.Length; k++) + for (int k = 0; k < SdCardKeyIdCount; k++) { Crypto.DecryptEcb(sdKek, SdCardKeySourcesSpecific[k], SdCardKeys[k], 0x20); } + + // Derive sd card save key + if (!SaveMacSdCardKekSource.IsEmpty() && !SaveMacSdCardKeySource.IsEmpty()) + { + var keySource = new byte[0x10]; + + for (int i = 0; i < 0x10; i++) + { + keySource[i] = (byte)(SaveMacSdCardKeySource[i] ^ SdSeed[i]); + } + + Crypto.GenerateKek(MasterKeys[0], SaveMacSdCardKekSource, sdKek, AesKekGenerationSource, null); + Crypto.DecryptEcb(sdKek, keySource, SaveMacSdCardKey, 0x10); + } } internal static readonly string[] KakNames = { "application", "ocean", "system" }; @@ -572,10 +591,13 @@ namespace LibHac new KeyValue("titlekek_source", 0x10, 100, set => set.TitleKekSource), new KeyValue("save_mac_kek_source", 0x10, 110, set => set.SaveMacKekSource), + new KeyValue("save_mac_sd_card_kek_source", 0x10, 110, set => set.SaveMacSdCardKekSource), new KeyValue("save_mac_key_source", 0x10, 110, set => set.SaveMacKeySource), + new KeyValue("save_mac_sd_card_key_source", 0x10, 110, set => set.SaveMacSdCardKeySource), new KeyValue("sd_card_kek_source", 0x10, 110, set => set.SdCardKekSource), - new KeyValue("sd_card_nca_key_source", 0x20, 110, set => set.SdCardKeySources[1]), new KeyValue("sd_card_save_key_source", 0x20, 110, set => set.SdCardKeySources[0]), + new KeyValue("sd_card_nca_key_source", 0x20, 110, set => set.SdCardKeySources[1]), + new KeyValue("sd_card_custom_storage_key_source", 0x20, 110, set => set.SdCardKeySources[2]), new KeyValue("eticket_rsa_kek", 0x10, 120, set => set.EticketRsaKek), new KeyValue("ssl_rsa_kek", 0x10, 120, set => set.SslRsaKek), @@ -620,7 +642,8 @@ namespace LibHac new KeyValue("sd_seed", 0x10, 10, set => set.SdSeed), new KeyValue("device_key", 0x10, 40, set => set.DeviceKey), - new KeyValue("save_mac_key", 0x10, 60, set => set.SaveMacKey) + new KeyValue("save_mac_key", 0x10, 60, set => set.SaveMacKey), + new KeyValue("save_mac_sd_card_key", 0x10, 60, set => set.SaveMacSdCardKey) }; for (int slot = 0; slot < 0x20; slot++)