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