|
|
|
@ -27,7 +27,7 @@
|
|
|
|
|
#include "core/file_sys/vfs_offset.h"
|
|
|
|
|
#include "core/file_sys/vfs_vector.h"
|
|
|
|
|
|
|
|
|
|
using namespace Common;
|
|
|
|
|
using Common::AsArray;
|
|
|
|
|
|
|
|
|
|
namespace Core::Crypto {
|
|
|
|
|
|
|
|
|
@ -47,105 +47,123 @@ struct Package2Header {
|
|
|
|
|
};
|
|
|
|
|
static_assert(sizeof(Package2Header) == 0x200, "Package2Header has incorrect size.");
|
|
|
|
|
|
|
|
|
|
const std::array<SHA256Hash, 0x10> source_hashes{
|
|
|
|
|
"B24BD293259DBC7AC5D63F88E60C59792498E6FC5443402C7FFE87EE8B61A3F0"_array32, // keyblob_mac_key_source
|
|
|
|
|
"7944862A3A5C31C6720595EFD302245ABD1B54CCDCF33000557681E65C5664A4"_array32, // master_key_source
|
|
|
|
|
"21E2DF100FC9E094DB51B47B9B1D6E94ED379DB8B547955BEF8FE08D8DD35603"_array32, // package2_key_source
|
|
|
|
|
"FC02B9D37B42D7A1452E71444F1F700311D1132E301A83B16062E72A78175085"_array32, // aes_kek_generation_source
|
|
|
|
|
"FBD10056999EDC7ACDB96098E47E2C3606230270D23281E671F0F389FC5BC585"_array32, // aes_key_generation_source
|
|
|
|
|
"C48B619827986C7F4E3081D59DB2B460C84312650E9A8E6B458E53E8CBCA4E87"_array32, // titlekek_source
|
|
|
|
|
"04AD66143C726B2A139FB6B21128B46F56C553B2B3887110304298D8D0092D9E"_array32, // key_area_key_application_source
|
|
|
|
|
"FD434000C8FF2B26F8E9A9D2D2C12F6BE5773CBB9DC86300E1BD99F8EA33A417"_array32, // key_area_key_ocean_source
|
|
|
|
|
"1F17B1FD51AD1C2379B58F152CA4912EC2106441E51722F38700D5937A1162F7"_array32, // key_area_key_system_source
|
|
|
|
|
"6B2ED877C2C52334AC51E59ABFA7EC457F4A7D01E46291E9F2EAA45F011D24B7"_array32, // sd_card_kek_source
|
|
|
|
|
"D482743563D3EA5DCDC3B74E97C9AC8A342164FA041A1DC80F17F6D31E4BC01C"_array32, // sd_card_save_key_source
|
|
|
|
|
"2E751CECF7D93A2B957BD5FFCB082FD038CC2853219DD3092C6DAB9838F5A7CC"_array32, // sd_card_nca_key_source
|
|
|
|
|
"1888CAED5551B3EDE01499E87CE0D86827F80820EFB275921055AA4E2ABDFFC2"_array32, // header_kek_source
|
|
|
|
|
"8F783E46852DF6BE0BA4E19273C4ADBAEE16380043E1B8C418C4089A8BD64AA6"_array32, // header_key_source
|
|
|
|
|
"D1757E52F1AE55FA882EC690BC6F954AC46A83DC22F277F8806BD55577C6EED7"_array32, // rsa_kek_seed3
|
|
|
|
|
"FC02B9D37B42D7A1452E71444F1F700311D1132E301A83B16062E72A78175085"_array32, // rsa_kek_mask0
|
|
|
|
|
// clang-format off
|
|
|
|
|
constexpr std::array source_hashes{
|
|
|
|
|
AsArray("B24BD293259DBC7AC5D63F88E60C59792498E6FC5443402C7FFE87EE8B61A3F0"), // keyblob_mac_key_source
|
|
|
|
|
AsArray("7944862A3A5C31C6720595EFD302245ABD1B54CCDCF33000557681E65C5664A4"), // master_key_source
|
|
|
|
|
AsArray("21E2DF100FC9E094DB51B47B9B1D6E94ED379DB8B547955BEF8FE08D8DD35603"), // package2_key_source
|
|
|
|
|
AsArray("FC02B9D37B42D7A1452E71444F1F700311D1132E301A83B16062E72A78175085"), // aes_kek_generation_source
|
|
|
|
|
AsArray("FBD10056999EDC7ACDB96098E47E2C3606230270D23281E671F0F389FC5BC585"), // aes_key_generation_source
|
|
|
|
|
AsArray("C48B619827986C7F4E3081D59DB2B460C84312650E9A8E6B458E53E8CBCA4E87"), // titlekek_source
|
|
|
|
|
AsArray("04AD66143C726B2A139FB6B21128B46F56C553B2B3887110304298D8D0092D9E"), // key_area_key_application_source
|
|
|
|
|
AsArray("FD434000C8FF2B26F8E9A9D2D2C12F6BE5773CBB9DC86300E1BD99F8EA33A417"), // key_area_key_ocean_source
|
|
|
|
|
AsArray("1F17B1FD51AD1C2379B58F152CA4912EC2106441E51722F38700D5937A1162F7"), // key_area_key_system_source
|
|
|
|
|
AsArray("6B2ED877C2C52334AC51E59ABFA7EC457F4A7D01E46291E9F2EAA45F011D24B7"), // sd_card_kek_source
|
|
|
|
|
AsArray("D482743563D3EA5DCDC3B74E97C9AC8A342164FA041A1DC80F17F6D31E4BC01C"), // sd_card_save_key_source
|
|
|
|
|
AsArray("2E751CECF7D93A2B957BD5FFCB082FD038CC2853219DD3092C6DAB9838F5A7CC"), // sd_card_nca_key_source
|
|
|
|
|
AsArray("1888CAED5551B3EDE01499E87CE0D86827F80820EFB275921055AA4E2ABDFFC2"), // header_kek_source
|
|
|
|
|
AsArray("8F783E46852DF6BE0BA4E19273C4ADBAEE16380043E1B8C418C4089A8BD64AA6"), // header_key_source
|
|
|
|
|
AsArray("D1757E52F1AE55FA882EC690BC6F954AC46A83DC22F277F8806BD55577C6EED7"), // rsa_kek_seed3
|
|
|
|
|
AsArray("FC02B9D37B42D7A1452E71444F1F700311D1132E301A83B16062E72A78175085"), // rsa_kek_mask0
|
|
|
|
|
};
|
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
|
|
const std::array<SHA256Hash, 0x20> keyblob_source_hashes{
|
|
|
|
|
"8A06FE274AC491436791FDB388BCDD3AB9943BD4DEF8094418CDAC150FD73786"_array32, // keyblob_key_source_00
|
|
|
|
|
"2D5CAEB2521FEF70B47E17D6D0F11F8CE2C1E442A979AD8035832C4E9FBCCC4B"_array32, // keyblob_key_source_01
|
|
|
|
|
"61C5005E713BAE780641683AF43E5F5C0E03671117F702F401282847D2FC6064"_array32, // keyblob_key_source_02
|
|
|
|
|
"8E9795928E1C4428E1B78F0BE724D7294D6934689C11B190943923B9D5B85903"_array32, // keyblob_key_source_03
|
|
|
|
|
"95FA33AF95AFF9D9B61D164655B32710ED8D615D46C7D6CC3CC70481B686B402"_array32, // keyblob_key_source_04
|
|
|
|
|
"3F5BE7B3C8B1ABD8C10B4B703D44766BA08730562C172A4FE0D6B866B3E2DB3E"_array32, // keyblob_key_source_05
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_06
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_07
|
|
|
|
|
// clang-format off
|
|
|
|
|
constexpr std::array keyblob_source_hashes{
|
|
|
|
|
AsArray("8A06FE274AC491436791FDB388BCDD3AB9943BD4DEF8094418CDAC150FD73786"), // keyblob_key_source_00
|
|
|
|
|
AsArray("2D5CAEB2521FEF70B47E17D6D0F11F8CE2C1E442A979AD8035832C4E9FBCCC4B"), // keyblob_key_source_01
|
|
|
|
|
AsArray("61C5005E713BAE780641683AF43E5F5C0E03671117F702F401282847D2FC6064"), // keyblob_key_source_02
|
|
|
|
|
AsArray("8E9795928E1C4428E1B78F0BE724D7294D6934689C11B190943923B9D5B85903"), // keyblob_key_source_03
|
|
|
|
|
AsArray("95FA33AF95AFF9D9B61D164655B32710ED8D615D46C7D6CC3CC70481B686B402"), // keyblob_key_source_04
|
|
|
|
|
AsArray("3F5BE7B3C8B1ABD8C10B4B703D44766BA08730562C172A4FE0D6B866B3E2DB3E"), // keyblob_key_source_05
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_06
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_07
|
|
|
|
|
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_08
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_09
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0A
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0B
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0C
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0D
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0E
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_0F
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_08
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_09
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0A
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0B
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0C
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0D
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0E
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_0F
|
|
|
|
|
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_10
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_11
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_12
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_13
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_14
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_15
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_16
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_17
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_10
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_11
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_12
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_13
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_14
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_15
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_16
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_17
|
|
|
|
|
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_18
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_19
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1A
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1B
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1C
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1D
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1E
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // keyblob_key_source_1F
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_18
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_19
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1A
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1B
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1C
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1D
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1E
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // keyblob_key_source_1F
|
|
|
|
|
};
|
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
|
|
const std::array<SHA256Hash, 0x20> master_key_hashes{
|
|
|
|
|
"0EE359BE3C864BB0782E1D70A718A0342C551EED28C369754F9C4F691BECF7CA"_array32, // master_key_00
|
|
|
|
|
"4FE707B7E4ABDAF727C894AAF13B1351BFE2AC90D875F73B2E20FA94B9CC661E"_array32, // master_key_01
|
|
|
|
|
"79277C0237A2252EC3DFAC1F7C359C2B3D121E9DB15BB9AB4C2B4408D2F3AE09"_array32, // master_key_02
|
|
|
|
|
"4F36C565D13325F65EE134073C6A578FFCB0008E02D69400836844EAB7432754"_array32, // master_key_03
|
|
|
|
|
"75FF1D95D26113550EE6FCC20ACB58E97EDEB3A2FF52543ED5AEC63BDCC3DA50"_array32, // master_key_04
|
|
|
|
|
"EBE2BCD6704673EC0F88A187BB2AD9F1CC82B718C389425941BDC194DC46B0DD"_array32, // master_key_05
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_06
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_07
|
|
|
|
|
// clang-format off
|
|
|
|
|
constexpr std::array master_key_hashes{
|
|
|
|
|
AsArray("0EE359BE3C864BB0782E1D70A718A0342C551EED28C369754F9C4F691BECF7CA"), // master_key_00
|
|
|
|
|
AsArray("4FE707B7E4ABDAF727C894AAF13B1351BFE2AC90D875F73B2E20FA94B9CC661E"), // master_key_01
|
|
|
|
|
AsArray("79277C0237A2252EC3DFAC1F7C359C2B3D121E9DB15BB9AB4C2B4408D2F3AE09"), // master_key_02
|
|
|
|
|
AsArray("4F36C565D13325F65EE134073C6A578FFCB0008E02D69400836844EAB7432754"), // master_key_03
|
|
|
|
|
AsArray("75FF1D95D26113550EE6FCC20ACB58E97EDEB3A2FF52543ED5AEC63BDCC3DA50"), // master_key_04
|
|
|
|
|
AsArray("EBE2BCD6704673EC0F88A187BB2AD9F1CC82B718C389425941BDC194DC46B0DD"), // master_key_05
|
|
|
|
|
AsArray("9497E6779F5D840F2BBA1DE4E95BA1D6F21EFC94717D5AE5CA37D7EC5BD37A19"), // master_key_06
|
|
|
|
|
AsArray("4EC96B8CB01B8DCE382149443430B2B6EBCB2983348AFA04A25E53609DABEDF6"), // master_key_07
|
|
|
|
|
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_08
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_09
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0A
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0B
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0C
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0D
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0E
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_0F
|
|
|
|
|
AsArray("2998E2E23609BC2675FF062A2D64AF5B1B78DFF463B24119D64A1B64F01B2D51"), // master_key_08
|
|
|
|
|
AsArray("9D486A98067C44B37CF173D3BF577891EB6081FF6B4A166347D9DBBF7025076B"), // master_key_09
|
|
|
|
|
AsArray("4EC5A237A75A083A9C5F6CF615601522A7F822D06BD4BA32612C9CEBBB29BD45"), // master_key_0A
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0B
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0C
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0D
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0E
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_0F
|
|
|
|
|
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_10
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_11
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_12
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_13
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_14
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_15
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_16
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_17
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_10
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_11
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_12
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_13
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_14
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_15
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_16
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_17
|
|
|
|
|
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_18
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_19
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1A
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1B
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1C
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1D
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1E
|
|
|
|
|
"0000000000000000000000000000000000000000000000000000000000000000"_array32, // master_key_1F
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_18
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_19
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1A
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1B
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1C
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1D
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1E
|
|
|
|
|
AsArray("0000000000000000000000000000000000000000000000000000000000000000"), // master_key_1F
|
|
|
|
|
};
|
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
|
|
static constexpr u8 CalculateMaxKeyblobSourceHash() {
|
|
|
|
|
const auto is_zero = [](const auto& data) {
|
|
|
|
|
// TODO: Replace with std::all_of whenever mingw decides to update their
|
|
|
|
|
// libraries to include the constexpr variant of it.
|
|
|
|
|
for (const auto element : data) {
|
|
|
|
|
if (element != 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static u8 CalculateMaxKeyblobSourceHash() {
|
|
|
|
|
for (s8 i = 0x1F; i >= 0; --i) {
|
|
|
|
|
if (keyblob_source_hashes[i] != SHA256Hash{})
|
|
|
|
|
if (!is_zero(keyblob_source_hashes[i])) {
|
|
|
|
|
return static_cast<u8>(i + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|