2021-09-28 11:15:54 +00:00
# include "KeyBag.h"
# include "util.h"
# include <tc/cli/FormatUtil.h>
2021-10-02 04:08:34 +00:00
# include <nn/hac/define/types.h>
2021-09-28 11:15:54 +00:00
# include <nn/hac/define/gc.h>
# include <nn/hac/AesKeygen.h>
# include <nn/pki/SignUtils.h>
# include <nn/pki/SignedData.h>
# include <nn/pki/CertificateBody.h>
# include <nn/es/TicketBody_V2.h>
nstool : : KeyBagInitializer : : KeyBagInitializer ( bool isDev , const tc : : Optional < tc : : io : : Path > & keyfile_path , const tc : : Optional < tc : : io : : Path > & tik_path , const tc : : Optional < tc : : io : : Path > & cert_path )
{
if ( keyfile_path . isSet ( ) )
{
importBaseKeyFile ( keyfile_path . get ( ) , isDev ) ;
}
if ( cert_path . isSet ( ) )
{
importCertificateChain ( cert_path . get ( ) ) ;
}
if ( tik_path . isSet ( ) )
{
importTicket ( tik_path . get ( ) ) ;
}
2021-10-02 04:08:34 +00:00
// this will populate known keys if they aren't supplied by the user provided keyfiles.
importKnownKeys ( isDev ) ;
2021-09-28 11:15:54 +00:00
}
void nstool : : KeyBagInitializer : : importBaseKeyFile ( const tc : : io : : Path & keyfile_path , bool isDev )
{
std : : shared_ptr < tc : : io : : FileStream > keyfile_stream = std : : make_shared < tc : : io : : FileStream > ( tc : : io : : FileStream ( keyfile_path , tc : : io : : FileMode : : Open , tc : : io : : FileAccess : : Read ) ) ;
// import keyfile into a dictionary
std : : map < std : : string , std : : string > keyfile_dict ;
processResFile ( keyfile_stream , keyfile_dict ) ;
// sources for key derivation
std : : map < byte_t , aes128_key_t > master_key ;
tc : : Optional < aes128_key_t > package2_key_source ;
tc : : Optional < aes128_key_t > ticket_titlekek_source ;
std : : array < tc : : Optional < aes128_key_t > , 3 > key_area_key_source ;
tc : : Optional < aes128_key_t > aes_kek_generation_source ;
tc : : Optional < aes128_key_t > aes_key_generation_source ;
tc : : Optional < aes128_key_t > nca_header_kek_source ;
tc : : Optional < aes128_xtskey_t > nca_header_key_source ;
tc : : Optional < rsa_key_t > pki_root_sign_key ;
// macros for importing
# define _SAVE_AES128KEY(key_name, dst) \
{ \
std : : string key , val ; \
tc : : ByteData dec_val ; \
aes128_key_t tmp_aes128_key ; \
key = ( key_name ) ; \
val = keyfile_dict [ key ] ; \
if ( val . empty ( ) = = false ) { \
dec_val = tc : : cli : : FormatUtil : : hexStringToBytes ( val ) ; \
if ( dec_val . size ( ) ! = tmp_aes128_key . size ( ) ) \
throw tc : : ArgumentException ( " nstool::KeyBagInitializer " , " Key: \" " + key_name + " \" has incorrect length " ) ; \
memcpy ( tmp_aes128_key . data ( ) , dec_val . data ( ) , tmp_aes128_key . size ( ) ) ; \
( dst ) = tmp_aes128_key ; \
} \
}
# define _SAVE_AES128XTSKEY(key_name, dst) \
{ \
std : : string key , val ; \
tc : : ByteData dec_val ; \
aes128_xtskey_t tmp_aes128_xtskey ; \
key = ( key_name ) ; \
val = keyfile_dict [ key ] ; \
if ( val . empty ( ) = = false ) { \
dec_val = tc : : cli : : FormatUtil : : hexStringToBytes ( val ) ; \
if ( dec_val . size ( ) ! = sizeof ( tmp_aes128_xtskey ) ) \
throw tc : : ArgumentException ( " nstool::KeyBagInitializer " , " Key: \" " + key_name + " \" has incorrect length " ) ; \
memcpy ( tmp_aes128_xtskey [ 0 ] . data ( ) , dec_val . data ( ) , tmp_aes128_xtskey [ 0 ] . size ( ) ) ; \
memcpy ( tmp_aes128_xtskey [ 1 ] . data ( ) , dec_val . data ( ) + tmp_aes128_xtskey [ 0 ] . size ( ) , tmp_aes128_xtskey [ 1 ] . size ( ) ) ; \
( dst ) = tmp_aes128_xtskey ; \
} \
}
# define _SAVE_RSAKEY(key_name, dst, bitsize) \
{ \
std : : string key_mod , key_prv , val_mod , val_prv ; \
tc : : ByteData dec_val ; \
rsa_key_t tmp_rsa_key ; \
key_mod = fmt : : format ( " {:s}_modulus " , ( key_name ) ) ; \
key_prv = fmt : : format ( " {:s}_private " , ( key_name ) ) ; \
val_mod = keyfile_dict [ key_mod ] ; \
val_prv = keyfile_dict [ key_prv ] ; \
if ( val_mod . empty ( ) = = false ) { \
dec_val = tc : : cli : : FormatUtil : : hexStringToBytes ( val_mod ) ; \
if ( dec_val . size ( ) = = ( bitsize ) > > 3 ) { \
tmp_rsa_key . n = dec_val ; \
if ( val_prv . empty ( ) = = false ) { \
dec_val = tc : : cli : : FormatUtil : : hexStringToBytes ( val_prv ) ; \
if ( dec_val . size ( ) = = ( bitsize ) > > 3 ) { \
tmp_rsa_key . d = dec_val ; \
( dst ) = tc : : crypto : : RsaPrivateKey ( tmp_rsa_key . n . data ( ) , tmp_rsa_key . n . size ( ) , tmp_rsa_key . d . data ( ) , tmp_rsa_key . d . size ( ) ) ; \
} \
else { \
fmt : : print ( " [WARNING] Key: \" {:s} \" has incorrect length (was: {:d}, expected {:d}) \n " , key_prv , val_prv . size ( ) , ( ( bitsize ) > > 3 ) * 2 ) ; \
} \
} \
else { \
( dst ) = tc : : crypto : : RsaPublicKey ( tmp_rsa_key . n . data ( ) , tmp_rsa_key . n . size ( ) ) ; \
} \
} \
else { \
fmt : : print ( " [WARNING] Key: \" {:s} \" has incorrect length (was: {:d}, expected {:d}) \n " , key_mod , val_mod . size ( ) , ( ( bitsize ) > > 3 ) * 2 ) ; \
} \
} \
}
// keynames
enum NameVariantIndex
{
NNTOOLS ,
LEGACY_HACTOOL ,
LEGACY_0
} ;
static const size_t kNameVariantNum = 3 ;
std : : vector < std : : string > kMasterBase = { " master " } ;
std : : vector < std : : string > kPkg1Base = { " package1 " } ;
std : : vector < std : : string > kPkg2Base = { " package2 " } ;
std : : vector < std : : string > kXciHeaderBase = { " xci_header " } ;
2021-10-08 09:59:27 +00:00
std : : vector < std : : string > kXciInitialDataBase = { " xci_initial_data " } ;
2021-10-02 04:15:32 +00:00
std : : vector < std : : string > kXciCertBase = { " xci_cert " } ;
2021-09-28 11:15:54 +00:00
std : : vector < std : : string > kContentArchiveHeaderBase = { " nca_header " , " header " } ;
std : : vector < std : : string > kAcidBase = { " acid " } ;
std : : vector < std : : string > kNrrCertBase = { " nrr_certificate " } ;
std : : vector < std : : string > kPkiRootBase = { " pki_root " } ;
std : : vector < std : : string > kTicketCommonKeyBase = { " ticket_commonkey " , " titlekek " } ;
std : : vector < std : : string > kNcaKeyAreaEncKeyBase = { " nca_key_area_key " , " key_area_key " , " nca_body_keak " } ;
std : : vector < std : : string > kNcaKeyAreaEncKeyHwBase = { " nca_key_area_key_hw " , " key_area_hw_key " } ;
std : : vector < std : : string > kKekGenBase = { " aes_kek_generation " } ;
std : : vector < std : : string > kKeyGenBase = { " aes_key_generation " } ;
// misc str
const std : : string kKeyStr = " key " ;
const std : : string kKekStr = " kek " ;
const std : : string kSourceStr = " source " ;
const std : : string kSignKey = " sign_key " ;
const std : : string kModulusStr = " modulus " ;
const std : : string kPrivateStr = " private " ;
std : : vector < std : : string > kNcaKeyAreaKeyIndexStr = { " application " , " ocean " , " system " } ;
2021-10-08 10:52:57 +00:00
static const size_t kKeyGenerationNum = 0x100 ;
2021-09-28 11:15:54 +00:00
/**/
// import key data
for ( size_t name_idx = 0 ; name_idx < kNameVariantNum ; name_idx + + )
{
/* internal key sources */
if ( name_idx < kMasterBase . size ( ) )
{
2021-10-08 10:52:57 +00:00
for ( size_t keygen_rev = 0 ; keygen_rev < kKeyGenerationNum ; keygen_rev + + )
2021-09-28 11:15:54 +00:00
{
// std::map<byte_t, aes128_key_t> master_key;
2021-10-08 10:52:57 +00:00
//fmt::print("{:s}_key_{:02x}\n", kMasterBase[name_idx], keygen_rev);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:s}_{:02x} " , kMasterBase [ name_idx ] , kKeyStr , keygen_rev ) , master_key [ ( byte_t ) keygen_rev ] ) ;
2021-09-28 11:15:54 +00:00
}
}
if ( name_idx < kPkg2Base . size ( ) )
{
// tc::Optional<aes128_key_t> package2_key_source;
//fmt::print("{:s}_key_source\n", kPkg2Base[name_idx]);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:s}_{:s} " , kPkg2Base [ name_idx ] , kKeyStr , kSourceStr ) , package2_key_source ) ;
}
if ( name_idx < kTicketCommonKeyBase . size ( ) )
{
// tc::Optional<aes128_key_t> ticket_titlekek_source;
//fmt::print("{:s}_source\n", kTicketCommonKeyBase[name_idx]);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:s} " , kTicketCommonKeyBase [ name_idx ] , kSourceStr ) , ticket_titlekek_source ) ;
}
if ( name_idx < kNcaKeyAreaEncKeyBase . size ( ) )
{
// std::array<tc::Optional<aes128_key_t>, 3> key_area_key_source;
for ( size_t keak_idx = 0 ; keak_idx < kNcaKeyAreaKeyIndexStr . size ( ) ; keak_idx + + )
{
//fmt::print("{:s}_{:s}_source\n", kNcaKeyAreaEncKeyBase[name_idx], kNcaKeyAreaKeyIndexStr[keak_idx]);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:s}_{:s} " , kNcaKeyAreaEncKeyBase [ name_idx ] , kNcaKeyAreaKeyIndexStr [ keak_idx ] , kSourceStr ) , key_area_key_source [ keak_idx ] ) ;
}
}
if ( name_idx < kKekGenBase . size ( ) )
{
// tc::Optional<aes128_key_t> aes_kek_generation_source;
//fmt::print("{:s}_source\n", kKekGenBase[name_idx]);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:s} " , kKekGenBase [ name_idx ] , kSourceStr ) , aes_kek_generation_source ) ;
}
if ( name_idx < kKeyGenBase . size ( ) )
{
// tc::Optional<aes128_key_t> aes_key_generation_source;
//fmt::print("{:s}_source\n", kKeyGenBase[name_idx]);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:s} " , kKeyGenBase [ name_idx ] , kSourceStr ) , aes_key_generation_source ) ;
}
if ( name_idx < kContentArchiveHeaderBase . size ( ) )
{
// tc::Optional<aes128_key_t> nca_header_kek_source;
//fmt::print("{:s}_kek_source\n", kContentArchiveHeaderBase[name_idx]);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:s}_{:s} " , kContentArchiveHeaderBase [ name_idx ] , kKekStr , kSourceStr ) , nca_header_kek_source ) ;
}
if ( name_idx < kContentArchiveHeaderBase . size ( ) )
{
// tc::Optional<aes128_xtskey_t> nca_header_key_source;
//fmt::print("{:s}_key_source\n", kContentArchiveHeaderBase[name_idx]);
_SAVE_AES128XTSKEY ( fmt : : format ( " {:s}_{:s}_{:s} " , kContentArchiveHeaderBase [ name_idx ] , kKeyStr , kSourceStr ) , nca_header_key_source ) ;
}
/* package1 */
// package1_key_xx
if ( name_idx < kPkg1Base . size ( ) )
{
2021-10-08 10:52:57 +00:00
for ( size_t keygen_rev = 0 ; keygen_rev < kKeyGenerationNum ; keygen_rev + + )
2021-09-28 11:15:54 +00:00
{
2021-10-08 10:52:57 +00:00
//fmt::print("{:s}_key_{:02x}\n", kPkg1Base[name_idx], keygen_rev);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:s}_{:02x} " , kPkg1Base [ name_idx ] , kKeyStr , keygen_rev ) , pkg1_key [ ( byte_t ) keygen_rev ] ) ;
2021-09-28 11:15:54 +00:00
}
}
/* package2 */
if ( name_idx < kPkg2Base . size ( ) )
{
// package2_key_xx
2021-10-08 10:52:57 +00:00
for ( size_t keygen_rev = 0 ; keygen_rev < kKeyGenerationNum ; keygen_rev + + )
2021-09-28 11:15:54 +00:00
{
2021-10-08 10:52:57 +00:00
//fmt::print("{:s}_key_{:02x}\n", kPkg2Base[name_idx], keygen_rev);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:s}_{:02x} " , kPkg2Base [ name_idx ] , kKeyStr , keygen_rev ) , pkg2_key [ ( byte_t ) keygen_rev ] ) ;
2021-09-28 11:15:54 +00:00
}
// package2_sign_key
//fmt::print("{:s}_{:s}_{:s}\n", kPkg2Base[name_idx], kSignKey, kPrivateStr);
//fmt::print("{:s}_{:s}_{:s}\n", kPkg2Base[name_idx], kSignKey, kModulusStr);
_SAVE_RSAKEY ( fmt : : format ( " {:s}_{:s} " , kPkg2Base [ name_idx ] , kSignKey ) , pkg2_sign_key , 2048 ) ;
}
/* eticket */
// ticket common key
if ( name_idx < kTicketCommonKeyBase . size ( ) )
{
2021-10-08 10:52:57 +00:00
for ( size_t keygen_rev = 0 ; keygen_rev < kKeyGenerationNum ; keygen_rev + + )
2021-09-28 11:15:54 +00:00
{
2021-10-08 10:52:57 +00:00
//fmt::print("{:s}_{:02x}\n", kTicketCommonKeyBase[name_idx], keygen_rev);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:02x} " , kTicketCommonKeyBase [ name_idx ] , keygen_rev ) , etik_common_key [ ( byte_t ) keygen_rev ] ) ;
2021-09-28 11:15:54 +00:00
}
}
/* NCA keys */
if ( name_idx < kContentArchiveHeaderBase . size ( ) )
{
// nca header key
//fmt::print("{:s}_{:s}\n", kContentArchiveHeaderBase[name_idx], kKeyStr);
//_SAVE_AES128XTSKEY(fmt::format("{:s}_{:s}", kContentArchiveHeaderBase[name_idx], kKeyStr), nca_header_key);
// nca header sign0 key (generations)
2021-10-08 10:52:57 +00:00
for ( size_t keygen_rev = 0 ; keygen_rev < kKeyGenerationNum ; keygen_rev + + )
2021-09-28 11:15:54 +00:00
{
2021-10-08 10:52:57 +00:00
//fmt::print("{:s}_{:s}_{:02x}_{:s}\n", kContentArchiveHeaderBase[name_idx], kSignKey, keygen_rev, kPrivateStr);
//fmt::print("{:s}_{:s}_{:02x}_{:s}\n", kContentArchiveHeaderBase[name_idx], kSignKey, keygen_rev, kModulusStr);
_SAVE_RSAKEY ( fmt : : format ( " {:s}_{:s}_{:02x} " , kContentArchiveHeaderBase [ name_idx ] , kSignKey , keygen_rev ) , nca_header_sign0_key [ ( byte_t ) keygen_rev ] , 2048 ) ;
2021-09-28 11:15:54 +00:00
}
// nca header sign0 key (generation 0)
//fmt::print("{:s}_{:s}_{:s}\n", kContentArchiveHeaderBase[name_idx], kSignKey, kPrivateStr);
//fmt::print("{:s}_{:s}_{:s}\n", kContentArchiveHeaderBase[name_idx], kSignKey, kModulusStr);
_SAVE_RSAKEY ( fmt : : format ( " {:s}_{:s} " , kContentArchiveHeaderBase [ name_idx ] , kSignKey ) , nca_header_sign0_key [ 0 ] , 2048 ) ;
}
// nca body key (unused since prototype format)
// nca key area encryption keys
if ( name_idx < kNcaKeyAreaEncKeyBase . size ( ) )
{
2021-10-08 10:52:57 +00:00
for ( size_t keygen_rev = 0 ; keygen_rev < kKeyGenerationNum ; keygen_rev + + )
2021-09-28 11:15:54 +00:00
{
for ( size_t keak_idx = 0 ; keak_idx < kNcaKeyAreaKeyIndexStr . size ( ) ; keak_idx + + )
{
2021-10-08 10:52:57 +00:00
//fmt::print("{:s}_{:s}_{:02x}\n", kNcaKeyAreaEncKeyBase[name_idx], kNcaKeyAreaKeyIndexStr[keak_idx], keygen_rev);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:s}_{:02x} " , kNcaKeyAreaEncKeyBase [ name_idx ] , kNcaKeyAreaKeyIndexStr [ keak_idx ] , keygen_rev ) , nca_key_area_encryption_key [ keak_idx ] [ ( byte_t ) keygen_rev ] ) ;
2021-09-28 11:15:54 +00:00
}
}
}
// nca key area "hw" encryption keys
if ( name_idx < kNcaKeyAreaEncKeyHwBase . size ( ) )
{
2021-10-08 10:52:57 +00:00
for ( size_t keygen_rev = 0 ; keygen_rev < kKeyGenerationNum ; keygen_rev + + )
2021-09-28 11:15:54 +00:00
{
for ( size_t keak_idx = 0 ; keak_idx < kNcaKeyAreaKeyIndexStr . size ( ) ; keak_idx + + )
{
2021-10-08 10:52:57 +00:00
//fmt::print("{:s}_{:s}_{:02x}\n", kNcaKeyAreaEncKeyHwBase[name_idx], kNcaKeyAreaKeyIndexStr[keak_idx], keygen_rev);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:s}_{:02x} " , kNcaKeyAreaEncKeyHwBase [ name_idx ] , kNcaKeyAreaKeyIndexStr [ keak_idx ] , keygen_rev ) , nca_key_area_encryption_key_hw [ keak_idx ] [ ( byte_t ) keygen_rev ] ) ;
2021-09-28 11:15:54 +00:00
}
}
}
/* ACID */
if ( name_idx < kAcidBase . size ( ) )
{
// acid sign key (generations)
2021-10-08 10:52:57 +00:00
for ( size_t keygen_rev = 0 ; keygen_rev < kKeyGenerationNum ; keygen_rev + + )
2021-09-28 11:15:54 +00:00
{
2021-10-08 10:52:57 +00:00
//fmt::print("{:s}_{:s}_{:02x}_{:s}\n", kAcidBase[name_idx], kSignKey, keygen_rev, kPrivateStr);
//fmt::print("{:s}_{:s}_{:02x}_{:s}\n", kAcidBase[name_idx], kSignKey, keygen_rev, kModulusStr);
_SAVE_RSAKEY ( fmt : : format ( " {:s}_{:s}_{:02x} " , kAcidBase [ name_idx ] , kSignKey , keygen_rev ) , acid_sign_key [ ( byte_t ) keygen_rev ] , 2048 ) ;
2021-09-28 11:15:54 +00:00
}
// acid sign key (generation 0)
//fmt::print("{:s}_{:s}_{:s}\n", kAcidBase[name_idx], kSignKey, kPrivateStr);
//fmt::print("{:s}_{:s}_{:s}\n", kAcidBase[name_idx], kSignKey, kModulusStr);
_SAVE_RSAKEY ( fmt : : format ( " {:s}_{:s} " , kAcidBase [ name_idx ] , kSignKey ) , acid_sign_key [ 0 ] , 2048 ) ;
}
/* NRR certificate */
if ( name_idx < kNrrCertBase . size ( ) )
{
// nrr certificate sign key (generations)
2021-10-08 10:52:57 +00:00
for ( size_t keygen_rev = 0 ; keygen_rev < kKeyGenerationNum ; keygen_rev + + )
2021-09-28 11:15:54 +00:00
{
2021-10-08 10:52:57 +00:00
//fmt::print("{:s}_{:s}_{:02x}_{:s}\n", kNrrCertBase[name_idx], kSignKey, keygen_rev, kPrivateStr);
//fmt::print("{:s}_{:s}_{:02x}_{:s}\n", kNrrCertBase[name_idx], kSignKey, keygen_rev, kModulusStr);
_SAVE_RSAKEY ( fmt : : format ( " {:s}_{:s}_{:02x} " , kNrrCertBase [ name_idx ] , kSignKey , keygen_rev ) , nrr_certificate_sign_key [ ( byte_t ) keygen_rev ] , 2048 ) ;
2021-09-28 11:15:54 +00:00
}
// nrr certificate sign key (generation 0)
//fmt::print("{:s}_{:s}_{:s}\n", kNrrCertBase[name_idx], kSignKey, kPrivateStr);
//fmt::print("{:s}_{:s}_{:s}\n", kNrrCertBase[name_idx], kSignKey, kModulusStr);
_SAVE_RSAKEY ( fmt : : format ( " {:s}_{:s} " , kNrrCertBase [ name_idx ] , kSignKey ) , nrr_certificate_sign_key [ 0 ] , 2048 ) ;
}
/* XCI header */
if ( name_idx < kXciHeaderBase . size ( ) )
{
// xci header key (based on index)
2021-10-08 10:52:57 +00:00
for ( byte_t kek_index = 0 ; kek_index < 8 ; kek_index + + )
2021-09-28 11:15:54 +00:00
{
//fmt::print("{:s}_{:s}_{:02x}\n", kXciHeaderBase[name_idx], kKeyStr, kek_index);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:s}_{:02x} " , kXciHeaderBase [ name_idx ] , kKeyStr , kek_index ) , xci_header_key [ kek_index ] ) ;
}
2021-10-02 04:08:34 +00:00
// xci header key (old label, prod/dev keys are actually a fake distinction, the are different key indexes available to both?, so select correct index when importing)
2021-09-28 11:15:54 +00:00
//fmt::print("{:s}_{:s}\n", kXciHeaderBase[name_idx], kKeyStr);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:s} " , kXciHeaderBase [ name_idx ] , kKeyStr ) , xci_header_key [ isDev ? nn : : hac : : gc : : KEK_DEV : nn : : hac : : gc : : KEK_PROD ] ) ;
// xci header sign key
//fmt::print("{:s}_{:s}_{:s}\n", kXciHeaderBase[name_idx], kSignKey, kPrivateStr);
//fmt::print("{:s}_{:s}_{:s}\n", kXciHeaderBase[name_idx], kSignKey, kModulusStr);
_SAVE_RSAKEY ( fmt : : format ( " {:s}_{:s} " , kXciHeaderBase [ name_idx ] , kSignKey ) , xci_header_sign_key , 2048 ) ;
}
2021-10-08 09:59:27 +00:00
/* XCI InitialData */
if ( name_idx < kXciInitialDataBase . size ( ) )
{
// xci initial data key (based on index)
2021-10-08 10:52:57 +00:00
for ( byte_t kek_index = 0 ; kek_index < 8 ; kek_index + + )
2021-10-08 09:59:27 +00:00
{
//fmt::print("{:s}_{:s}_{:02x}\n", kXciInitialDataBase[name_idx], kKekStr, kek_index);
_SAVE_AES128KEY ( fmt : : format ( " {:s}_{:s}_{:02x} " , kXciInitialDataBase [ name_idx ] , kKekStr , kek_index ) , xci_initial_data_kek [ kek_index ] ) ;
}
}
2021-10-02 04:15:32 +00:00
/* XCI cert */
if ( name_idx < kXciCertBase . size ( ) )
{
// xci cert sign key
_SAVE_RSAKEY ( fmt : : format ( " {:s}_{:s} " , kXciCertBase [ name_idx ] , kSignKey ) , xci_cert_sign_key , 2048 ) ;
}
2021-09-28 11:15:54 +00:00
/* PKI */
if ( name_idx < kPkiRootBase . size ( ) )
{
// tc::Optional<rsa_key_t> pki_root_sign_key;
//fmt::print("{:s}_{:s}_{:s}\n", kPkiRootBase[name_idx], kSignKey, kPrivateStr);
//fmt::print("{:s}_{:s}_{:s}\n", kPkiRootBase[name_idx], kSignKey, kModulusStr);
_SAVE_RSAKEY ( fmt : : format ( " {:s}_{:s} " , kPkiRootBase [ name_idx ] , kSignKey ) , pki_root_sign_key , 4096 ) ;
}
}
# undef _SAVE_RSAKEY
# undef _SAVE_AES128XTSKEY
# undef _SAVE_AES128KEY
// Derive Keys
for ( auto itr = master_key . begin ( ) ; itr ! = master_key . end ( ) ; itr + + )
{
if ( aes_kek_generation_source . isSet ( ) & & aes_key_generation_source . isSet ( ) )
{
if ( itr - > first = = 0 & & nca_header_kek_source . isSet ( ) & & nca_header_key_source . isSet ( ) )
{
if ( nca_header_key . isNull ( ) )
{
aes128_key_t nca_header_kek_tmp ;
nn : : hac : : AesKeygen : : generateKey ( nca_header_kek_tmp . data ( ) , aes_kek_generation_source . get ( ) . data ( ) , nca_header_kek_source . get ( ) . data ( ) , aes_key_generation_source . get ( ) . data ( ) , itr - > second . data ( ) ) ;
aes128_xtskey_t nca_header_key_tmp ;
nn : : hac : : AesKeygen : : generateKey ( nca_header_key_tmp [ 0 ] . data ( ) , nca_header_key_source . get ( ) [ 0 ] . data ( ) , nca_header_kek_tmp . data ( ) ) ;
nn : : hac : : AesKeygen : : generateKey ( nca_header_key_tmp [ 1 ] . data ( ) , nca_header_key_source . get ( ) [ 1 ] . data ( ) , nca_header_kek_tmp . data ( ) ) ;
nca_header_key = nca_header_key_tmp ;
}
}
for ( size_t keak_idx = 0 ; keak_idx < nn : : hac : : nca : : kKeyAreaEncryptionKeyNum ; keak_idx + + )
{
if ( key_area_key_source [ keak_idx ] . isSet ( ) & & nca_key_area_encryption_key [ keak_idx ] . find ( itr - > first ) ! = nca_key_area_encryption_key [ keak_idx ] . end ( ) )
{
aes128_key_t nca_key_area_encryption_key_tmp ;
nn : : hac : : AesKeygen : : generateKey ( nca_key_area_encryption_key_tmp . data ( ) , aes_kek_generation_source . get ( ) . data ( ) , key_area_key_source [ keak_idx ] . get ( ) . data ( ) , aes_key_generation_source . get ( ) . data ( ) , itr - > second . data ( ) ) ;
nca_key_area_encryption_key [ keak_idx ] [ itr - > first ] = nca_key_area_encryption_key_tmp ;
}
}
}
if ( ticket_titlekek_source . isSet ( ) & & etik_common_key . find ( itr - > first ) = = etik_common_key . end ( ) )
{
aes128_key_t etik_common_key_tmp ;
nn : : hac : : AesKeygen : : generateKey ( etik_common_key_tmp . data ( ) , ticket_titlekek_source . get ( ) . data ( ) , itr - > second . data ( ) ) ;
etik_common_key [ itr - > first ] = etik_common_key_tmp ;
}
if ( package2_key_source . isSet ( ) & & pkg2_key . find ( itr - > first ) = = pkg2_key . end ( ) )
{
aes128_key_t pkg2_key_tmp ;
nn : : hac : : AesKeygen : : generateKey ( pkg2_key_tmp . data ( ) , package2_key_source . get ( ) . data ( ) , itr - > second . data ( ) ) ;
pkg2_key [ itr - > first ] = pkg2_key_tmp ;
}
}
// Save PKI Root Key
if ( pki_root_sign_key . isSet ( ) )
{
2021-09-30 11:40:27 +00:00
broadon_signer [ " Root " ] = { tc : : ByteData ( ) , nn : : pki : : sign : : SIGN_ALGO_RSA4096 , pki_root_sign_key . get ( ) } ;
2021-09-28 11:15:54 +00:00
}
}
void nstool : : KeyBagInitializer : : importTitleKeyFile ( const tc : : io : : Path & keyfile_path )
{
}
void nstool : : KeyBagInitializer : : importCertificateChain ( const tc : : io : : Path & cert_path )
{
// save file path string for error messages
std : : string cert_path_str ;
tc : : io : : PathUtil : : pathToUnixUTF8 ( cert_path , cert_path_str ) ;
// open cert file
std : : shared_ptr < tc : : io : : FileStream > certfile_stream ;
try {
certfile_stream = std : : make_shared < tc : : io : : FileStream > ( tc : : io : : FileStream ( cert_path , tc : : io : : FileMode : : Open , tc : : io : : FileAccess : : Read ) ) ;
}
catch ( tc : : io : : FileNotFoundException & e ) {
fmt : : print ( " [WARNING] Failed to open certificate file \" {:s} \" ({:s}). \n " , cert_path_str , e . error ( ) ) ;
return ;
}
// check size
size_t cert_raw_size = tc : : io : : IOUtil : : castInt64ToSize ( certfile_stream - > length ( ) ) ;
if ( cert_raw_size > 0x10000 )
{
fmt : : print ( " [WARNING] Certificate file \" {:s} \" was too large. \n " , cert_path_str ) ;
return ;
}
// import cert data
tc : : ByteData cert_raw = tc : : ByteData ( cert_raw_size ) ;
certfile_stream - > seek ( 0 , tc : : io : : SeekOrigin : : Begin ) ;
certfile_stream - > read ( cert_raw . data ( ) , cert_raw . size ( ) ) ;
nn : : pki : : SignedData < nn : : pki : : CertificateBody > cert ;
try {
for ( size_t f_pos = 0 ; f_pos < cert_raw . size ( ) ; f_pos + = cert . getBytes ( ) . size ( ) )
{
cert . fromBytes ( cert_raw . data ( ) + f_pos , cert_raw . size ( ) - f_pos ) ;
std : : string cert_identity = fmt : : format ( " {:s}-{:s} " , cert . getBody ( ) . getIssuer ( ) , cert . getBody ( ) . getSubject ( ) ) ;
switch ( cert . getBody ( ) . getPublicKeyType ( ) ) {
case nn : : pki : : cert : : PublicKeyType : : RSA2048 :
2021-09-30 11:40:27 +00:00
broadon_signer [ cert_identity ] = { cert . getBytes ( ) , nn : : pki : : sign : : SIGN_ALGO_RSA2048 , cert . getBody ( ) . getRsa2048PublicKey ( ) } ;
2021-09-28 11:15:54 +00:00
break ;
case nn : : pki : : cert : : PublicKeyType : : RSA4096 :
2021-09-30 11:40:27 +00:00
broadon_signer [ cert_identity ] = { cert . getBytes ( ) , nn : : pki : : sign : : SIGN_ALGO_RSA4096 , cert . getBody ( ) . getRsa4096PublicKey ( ) } ;
2021-09-28 11:15:54 +00:00
break ;
case nn : : pki : : cert : : PublicKeyType : : ECDSA240 :
2021-09-30 11:40:27 +00:00
// broadon_signer[cert_identity] = { cert.getBytes(), nn::pki::sign::SIGN_ALGO_ECDSA240, cert.getBody().getRsa4096PublicKey() };
2021-09-28 11:15:54 +00:00
fmt : : print ( " [WARNING] Certificate {:s} will not be imported. ecc233 public keys are not supported yet. \n " , cert_identity ) ;
break ;
default :
fmt : : print ( " [WARNING] Certificate {:s} will not be imported. Unknown public key type. \n " , cert_identity ) ;
}
}
}
catch ( tc : : Exception & e ) {
fmt : : print ( " [WARNING] Certificate file \" {:s} \" is corrupted ({:s}). \n " , cert_path_str , e . error ( ) ) ;
return ;
}
}
void nstool : : KeyBagInitializer : : importTicket ( const tc : : io : : Path & tik_path )
{
// save file path string for error messages
std : : string tik_path_str ;
tc : : io : : PathUtil : : pathToUnixUTF8 ( tik_path , tik_path_str ) ;
// open cert file
std : : shared_ptr < tc : : io : : FileStream > tik_stream ;
try {
tik_stream = std : : make_shared < tc : : io : : FileStream > ( tc : : io : : FileStream ( tik_path , tc : : io : : FileMode : : Open , tc : : io : : FileAccess : : Read ) ) ;
}
catch ( tc : : io : : FileNotFoundException & e ) {
fmt : : print ( " [WARNING] Failed to open ticket \" {:s} \" ({:s}). \n " , tik_path_str , e . error ( ) ) ;
return ;
}
// check size
size_t tik_raw_size = tc : : io : : IOUtil : : castInt64ToSize ( tik_stream - > length ( ) ) ;
if ( tik_raw_size > 0x10000 )
{
fmt : : print ( " [WARNING] Ticket \" {:s} \" was too large. \n " , tik_path_str ) ;
return ;
}
// import cert data
tc : : ByteData tik_raw = tc : : ByteData ( tik_raw_size ) ;
tik_stream - > seek ( 0 , tc : : io : : SeekOrigin : : Begin ) ;
tik_stream - > read ( tik_raw . data ( ) , tik_raw . size ( ) ) ;
nn : : pki : : SignedData < nn : : es : : TicketBody_V2 > tik ;
try {
// de serialise ticket
tik . fromBytes ( tik_raw . data ( ) , tik_raw . size ( ) ) ;
// save rights id
rights_id_t rights_id ;
memcpy ( rights_id . data ( ) , tik . getBody ( ) . getRightsId ( ) , rights_id . size ( ) ) ;
// check ticket is not personalised
if ( tik . getBody ( ) . getTitleKeyEncType ( ) ! = nn : : es : : ticket : : AES128_CBC )
{
fmt : : print ( " [WARNING] Ticket \" {:s} \" will not be imported. Personalised tickets are not supported. \n " , tc : : cli : : FormatUtil : : formatBytesAsString ( rights_id . data ( ) , rights_id . size ( ) , true , " " ) ) ;
return ;
}
// save enc title key
aes128_key_t enc_title_key ;
memcpy ( enc_title_key . data ( ) , tik . getBody ( ) . getEncTitleKey ( ) , enc_title_key . size ( ) ) ;
// save the encrypted title key as the fallback enc content key incase the ticket was malformed and workarounds to decrypt it in isolation fail
if ( fallback_enc_content_key . isNull ( ) )
{
fallback_enc_content_key = enc_title_key ;
}
// determine key to decrypt title key
byte_t common_key_index = tik . getBody ( ) . getCommonKeyId ( ) ;
// work around for bad scene tickets where they don't set the commonkey id field (detect scene ticket with ffff.... signature)
2021-10-21 20:12:03 +00:00
if ( common_key_index = = 0 & & * ( ( uint64_t * ) tik . getSignature ( ) . getSignature ( ) . data ( ) ) = = ( uint64_t ) 0xffffffffffffffff )
2021-09-28 11:15:54 +00:00
{
2021-10-21 20:12:03 +00:00
fmt : : print ( " [WARNING] Ticket \" {:s} \" is fake-signed, and NCA decryption may fail if ticket was incorrectly generated. " , tc : : cli : : FormatUtil : : formatBytesAsString ( rights_id . data ( ) , rights_id . size ( ) , true , " " ) ) ;
// the keygeneration was included in the rights_id from keygeneration 0x03 and onwards, so in those cases we can copy from there
if ( rights_id [ 15 ] > = 0x03 )
common_key_index = rights_id [ 15 ] ;
2021-09-28 11:15:54 +00:00
}
2021-10-19 08:22:59 +00:00
// convert key_generation
common_key_index = nn : : hac : : AesKeygen : : getMasterKeyRevisionFromKeyGeneration ( common_key_index ) ;
if ( etik_common_key . find ( common_key_index ) = = etik_common_key . end ( ) )
2021-09-28 11:15:54 +00:00
{
fmt : : print ( " [WARNING] Ticket \" {:s} \" will not be imported. Could not decrypt title key. \n " , tc : : cli : : FormatUtil : : formatBytesAsString ( rights_id . data ( ) , rights_id . size ( ) , true , " " ) ) ;
return ;
}
2021-10-19 08:22:59 +00:00
fmt : : print ( " [TIK] decrypt title key with index 0x{:x} \n " , common_key_index ) ;
2021-09-28 11:15:54 +00:00
// decrypt title key
aes128_key_t dec_title_key ;
tc : : crypto : : DecryptAes128Ecb ( dec_title_key . data ( ) , enc_title_key . data ( ) , sizeof ( aes128_key_t ) , etik_common_key [ common_key_index ] . data ( ) , sizeof ( aes128_key_t ) ) ;
// add to key dict
external_content_keys [ rights_id ] = dec_title_key ;
}
catch ( tc : : Exception & e ) {
fmt : : print ( " [WARNING] Ticket \" {:s} \" is corrupted ({:s}). \n " , tik_path_str , e . error ( ) ) ;
return ;
}
2021-10-02 04:08:34 +00:00
}
void nstool : : KeyBagInitializer : : importKnownKeys ( bool isDev )
{
static const nn : : hac : : detail : : rsa2048_block_t kXciHeaderSignModulus = {
0x98 , 0xC7 , 0x26 , 0xB6 , 0x0D , 0x0A , 0x50 , 0xA7 , 0x39 , 0x21 , 0x0A , 0xE3 , 0x2F , 0xE4 , 0x3E , 0x2E ,
0x5B , 0xA2 , 0x86 , 0x75 , 0xAA , 0x5C , 0xEE , 0x34 , 0xF1 , 0xA3 , 0x3A , 0x7E , 0xBD , 0x90 , 0x4E , 0xF7 ,
0x8D , 0xFA , 0x17 , 0xAA , 0x6B , 0xC6 , 0x36 , 0x6D , 0x4C , 0x9A , 0x6D , 0x57 , 0x2F , 0x80 , 0xA2 , 0xBC ,
0x38 , 0x4D , 0xDA , 0x99 , 0xA1 , 0xD8 , 0xC3 , 0xE2 , 0x99 , 0x79 , 0x36 , 0x71 , 0x90 , 0x20 , 0x25 , 0x9D ,
0x4D , 0x11 , 0xB8 , 0x2E , 0x63 , 0x6B , 0x5A , 0xFA , 0x1E , 0x9C , 0x04 , 0xD1 , 0xC5 , 0xF0 , 0x9C , 0xB1 ,
0x0F , 0xB8 , 0xC1 , 0x7B , 0xBF , 0xE8 , 0xB0 , 0xD2 , 0x2B , 0x47 , 0x01 , 0x22 , 0x6B , 0x23 , 0xC9 , 0xD0 ,
0xBC , 0xEB , 0x75 , 0x6E , 0x41 , 0x7D , 0x4C , 0x26 , 0xA4 , 0x73 , 0x21 , 0xB4 , 0xF0 , 0x14 , 0xE5 , 0xD9 ,
0x8D , 0xB3 , 0x64 , 0xEE , 0xA8 , 0xFA , 0x84 , 0x1B , 0xB8 , 0xB8 , 0x7C , 0x88 , 0x6B , 0xEF , 0xCC , 0x97 ,
0x04 , 0x04 , 0x9A , 0x67 , 0x2F , 0xDF , 0xEC , 0x0D , 0xB2 , 0x5F , 0xB5 , 0xB2 , 0xBD , 0xB5 , 0x4B , 0xDE ,
0x0E , 0x88 , 0xA3 , 0xBA , 0xD1 , 0xB4 , 0xE0 , 0x91 , 0x81 , 0xA7 , 0x84 , 0xEB , 0x77 , 0x85 , 0x8B , 0xEF ,
0xA5 , 0xE3 , 0x27 , 0xB2 , 0xF2 , 0x82 , 0x2B , 0x29 , 0xF1 , 0x75 , 0x2D , 0xCE , 0xCC , 0xAE , 0x9B , 0x8D ,
0xED , 0x5C , 0xF1 , 0x8E , 0xDB , 0x9A , 0xD7 , 0xAF , 0x42 , 0x14 , 0x52 , 0xCD , 0xE3 , 0xC5 , 0xDD , 0xCE ,
0x08 , 0x12 , 0x17 , 0xD0 , 0x7F , 0x1A , 0xAA , 0x1F , 0x7D , 0xE0 , 0x93 , 0x54 , 0xC8 , 0xBC , 0x73 , 0x8A ,
0xCB , 0xAD , 0x6E , 0x93 , 0xE2 , 0x19 , 0x72 , 0x6B , 0xD3 , 0x45 , 0xF8 , 0x73 , 0x3D , 0x2B , 0x6A , 0x55 ,
0xD2 , 0x3A , 0x8B , 0xB0 , 0x8A , 0x42 , 0xE3 , 0x3D , 0xF1 , 0x92 , 0x23 , 0x42 , 0x2E , 0xBA , 0xCC , 0x9C ,
0x9A , 0xC1 , 0xDD , 0x62 , 0x86 , 0x9C , 0x2E , 0xE1 , 0x2D , 0x6F , 0x62 , 0x67 , 0x51 , 0x08 , 0x0E , 0xCF
} ;
static const nn : : hac : : detail : : rsa2048_block_t kXciCertSignModulus = {
0xCD , 0xF3 , 0x2C , 0xB0 , 0xF5 , 0x14 , 0x78 , 0x34 , 0xE5 , 0x02 , 0xD0 , 0x29 , 0x6A , 0xA5 , 0xFD , 0x97 ,
0x6A , 0xE0 , 0xB0 , 0xBB , 0xB0 , 0x3B , 0x1A , 0x80 , 0xB7 , 0xD7 , 0x58 , 0x92 , 0x79 , 0x84 , 0xC0 , 0x36 ,
0xB1 , 0x55 , 0x23 , 0xD8 , 0xA5 , 0x60 , 0x91 , 0x26 , 0x48 , 0x1A , 0x80 , 0x4A , 0xEA , 0x00 , 0x98 , 0x2A ,
0xEC , 0x52 , 0x17 , 0x72 , 0x92 , 0x4D , 0xF5 , 0x42 , 0xA7 , 0x8A , 0x6F , 0x7F , 0xD2 , 0x48 , 0x51 , 0x8E ,
0xDF , 0xCB , 0xBF , 0x77 , 0xF6 , 0x18 , 0xBD , 0xE5 , 0x00 , 0xD9 , 0x70 , 0x8C , 0xEF , 0x57 , 0xB2 , 0x96 ,
0xD0 , 0x36 , 0x83 , 0x88 , 0x9C , 0xC5 , 0xFB , 0xA0 , 0x33 , 0x81 , 0xA2 , 0x12 , 0x23 , 0xC6 , 0xC7 , 0x86 ,
0x0A , 0x98 , 0x57 , 0x4D , 0x2E , 0xB5 , 0xAE , 0x64 , 0xE4 , 0x6F , 0xC2 , 0xC5 , 0xAC , 0x6A , 0x1D , 0xDB ,
0xA5 , 0xAF , 0x12 , 0x22 , 0xAB , 0x1F , 0x51 , 0xC8 , 0x0E , 0x0D , 0xC9 , 0xF5 , 0x03 , 0xE8 , 0xD2 , 0xFC ,
0x84 , 0x62 , 0x26 , 0x55 , 0xA4 , 0xC3 , 0xE2 , 0xA8 , 0x98 , 0x05 , 0x67 , 0x23 , 0xFD , 0xA5 , 0x46 , 0x40 ,
0x78 , 0x51 , 0x09 , 0x3D , 0x91 , 0x74 , 0xD6 , 0xD0 , 0x54 , 0x23 , 0x0D , 0xA0 , 0xFB , 0x07 , 0xD0 , 0xAA ,
0x9D , 0x50 , 0x4E , 0x2B , 0x26 , 0x9A , 0x14 , 0xE5 , 0x6C , 0x73 , 0x66 , 0x24 , 0x18 , 0xA1 , 0x93 , 0x9C ,
0x2A , 0x40 , 0x40 , 0x05 , 0x6B , 0xF1 , 0x45 , 0xDF , 0x22 , 0x8B , 0x40 , 0x61 , 0xA4 , 0x11 , 0x06 , 0x03 ,
0xA5 , 0x53 , 0x84 , 0xC0 , 0x12 , 0xE1 , 0x88 , 0x9D , 0x55 , 0x55 , 0x07 , 0x40 , 0x88 , 0x01 , 0x8C , 0xAB ,
0xA2 , 0xFD , 0xFD , 0x19 , 0x48 , 0x25 , 0xAB , 0x59 , 0x59 , 0x28 , 0x63 , 0x68 , 0x69 , 0x1B , 0x99 , 0x73 ,
0x8D , 0xAB , 0x5A , 0xFA , 0x71 , 0x60 , 0x1B , 0x12 , 0xE7 , 0x99 , 0x70 , 0xF1 , 0x99 , 0x2A , 0x50 , 0x18 ,
0x8B , 0x6B , 0x61 , 0x90 , 0xE2 , 0x7E , 0x8B , 0x90 , 0xD4 , 0xD5 , 0xC0 , 0xCB , 0x7C , 0x08 , 0x06 , 0xD9
} ;
/* Keydata for very early beta NCA0 archives' RSA-OAEP. */
/*
static const nn : : hac : : detail : : rsa2048_block_t beta_nca0_modulus = {
0xAD , 0x58 , 0xEE , 0x97 , 0xF9 , 0x47 , 0x90 , 0x7D , 0xF9 , 0x29 , 0x5F , 0x1F , 0x39 , 0x68 , 0xEE , 0x49 ,
0x4C , 0x1E , 0x8D , 0x84 , 0x91 , 0x31 , 0x5D , 0xE5 , 0x96 , 0x27 , 0xB2 , 0xB3 , 0x59 , 0x7B , 0xDE , 0xFD ,
0xB7 , 0xEB , 0x40 , 0xA1 , 0xE7 , 0xEB , 0xDC , 0x60 , 0xD0 , 0x3D , 0xC5 , 0x50 , 0x92 , 0xAD , 0x3D , 0xC4 ,
0x8C , 0x17 , 0xD2 , 0x37 , 0x66 , 0xE3 , 0xF7 , 0x14 , 0x34 , 0x38 , 0x6B , 0xA7 , 0x2B , 0x21 , 0x10 , 0x9B ,
0x73 , 0x49 , 0x15 , 0xD9 , 0x2A , 0x90 , 0x86 , 0x76 , 0x81 , 0x6A , 0x10 , 0xBD , 0x74 , 0xC4 , 0x20 , 0x55 ,
0x25 , 0xA8 , 0x02 , 0xC5 , 0xA0 , 0x34 , 0x36 , 0x7B , 0x66 , 0x47 , 0x2C , 0x7E , 0x47 , 0x82 , 0xA5 , 0xD4 ,
0xA3 , 0x42 , 0x45 , 0xE8 , 0xFD , 0x65 , 0x72 , 0x48 , 0xA1 , 0xB0 , 0x44 , 0x10 , 0xEF , 0xAC , 0x1D , 0x0F ,
0xB5 , 0x12 , 0x19 , 0xA8 , 0x41 , 0x0B , 0x76 , 0x3B , 0xBC , 0xF1 , 0x4A , 0x10 , 0x46 , 0x22 , 0xB8 , 0xF1 ,
0xBC , 0x21 , 0x81 , 0x69 , 0x9B , 0x63 , 0x6F , 0xD7 , 0xB9 , 0x60 , 0x2A , 0x9A , 0xE5 , 0x2C , 0x47 , 0x72 ,
0x59 , 0x65 , 0xA2 , 0x21 , 0x60 , 0xC4 , 0xFC , 0xB0 , 0xD7 , 0x6F , 0x42 , 0xC9 , 0x0C , 0xF5 , 0x76 , 0x7D ,
0xF2 , 0x5C , 0xE0 , 0x80 , 0x0F , 0xEE , 0x45 , 0x7E , 0x4E , 0x3A , 0x8D , 0x9C , 0x5B , 0x5B , 0xD9 , 0xD1 ,
0x43 , 0x94 , 0x2C , 0xC7 , 0x2E , 0xB9 , 0x4A , 0xE5 , 0x3E , 0x15 , 0xDD , 0x43 , 0x00 , 0xF7 , 0x78 , 0xE7 ,
0x7C , 0x39 , 0xB0 , 0x4D , 0xC5 , 0xD1 , 0x1C , 0xF2 , 0xB4 , 0x7A , 0x2A , 0xEA , 0x0A , 0x8E , 0xB9 , 0x13 ,
0xB4 , 0x4F , 0xD7 , 0x5B , 0x4D , 0x7B , 0x43 , 0xB0 , 0x3A , 0x9A , 0x60 , 0x22 , 0x47 , 0x91 , 0x78 , 0xC7 ,
0x10 , 0x64 , 0xE0 , 0x2C , 0x69 , 0xD1 , 0x66 , 0x3C , 0x42 , 0x2E , 0xEF , 0x19 , 0x21 , 0x89 , 0x8E , 0xE1 ,
0xB0 , 0xB4 , 0xD0 , 0x17 , 0xA1 , 0x0F , 0x73 , 0x98 , 0x5A , 0xF6 , 0xEE , 0xC0 , 0x2F , 0x9E , 0xCE , 0xC5
} ;
static const nn : : hac : : detail : : sha256_hash_t beta_nca0_label_hash = {
0xE3 , 0xB0 , 0xC4 , 0x42 , 0x98 , 0xFC , 0x1C , 0x14 , 0x9A , 0xFB , 0xF4 , 0xC8 , 0x99 , 0x6F , 0xB9 , 0x24 ,
0x27 , 0xAE , 0x41 , 0xE4 , 0x64 , 0x9B , 0x93 , 0x4C , 0xA4 , 0x95 , 0x99 , 0x1B , 0x78 , 0x52 , 0xB8 , 0x55
} ;
*/
struct sRsaKeyForGeneration {
byte_t generation ;
nn : : hac : : detail : : rsa2048_block_t modulus ;
} ;
static const nn : : hac : : detail : : rsa2048_block_t kProdPackage2HeaderModulus = {
0x8D , 0x13 , 0xA7 , 0x77 , 0x6A , 0xE5 , 0xDC , 0xC0 , 0x3B , 0x25 , 0xD0 , 0x58 , 0xE4 , 0x20 , 0x69 , 0x59 ,
0x55 , 0x4B , 0xAB , 0x70 , 0x40 , 0x08 , 0x28 , 0x07 , 0xA8 , 0xA7 , 0xFD , 0x0F , 0x31 , 0x2E , 0x11 , 0xFE ,
0x47 , 0xA0 , 0xF9 , 0x9D , 0xDF , 0x80 , 0xDB , 0x86 , 0x5A , 0x27 , 0x89 , 0xCD , 0x97 , 0x6C , 0x85 , 0xC5 ,
0x6C , 0x39 , 0x7F , 0x41 , 0xF2 , 0xFF , 0x24 , 0x20 , 0xC3 , 0x95 , 0xA6 , 0xF7 , 0x9D , 0x4A , 0x45 , 0x74 ,
0x8B , 0x5D , 0x28 , 0x8A , 0xC6 , 0x99 , 0x35 , 0x68 , 0x85 , 0xA5 , 0x64 , 0x32 , 0x80 , 0x9F , 0xD3 , 0x48 ,
0x39 , 0xA2 , 0x1D , 0x24 , 0x67 , 0x69 , 0xDF , 0x75 , 0xAC , 0x12 , 0xB5 , 0xBD , 0xC3 , 0x29 , 0x90 , 0xBE ,
0x37 , 0xE4 , 0xA0 , 0x80 , 0x9A , 0xBE , 0x36 , 0xBF , 0x1F , 0x2C , 0xAB , 0x2B , 0xAD , 0xF5 , 0x97 , 0x32 ,
0x9A , 0x42 , 0x9D , 0x09 , 0x8B , 0x08 , 0xF0 , 0x63 , 0x47 , 0xA3 , 0xE9 , 0x1B , 0x36 , 0xD8 , 0x2D , 0x8A ,
0xD7 , 0xE1 , 0x54 , 0x11 , 0x95 , 0xE4 , 0x45 , 0x88 , 0x69 , 0x8A , 0x2B , 0x35 , 0xCE , 0xD0 , 0xA5 , 0x0B ,
0xD5 , 0x5D , 0xAC , 0xDB , 0xAF , 0x11 , 0x4D , 0xCA , 0xB8 , 0x1E , 0xE7 , 0x01 , 0x9E , 0xF4 , 0x46 , 0xA3 ,
0x8A , 0x94 , 0x6D , 0x76 , 0xBD , 0x8A , 0xC8 , 0x3B , 0xD2 , 0x31 , 0x58 , 0x0C , 0x79 , 0xA8 , 0x26 , 0xE9 ,
0xD1 , 0x79 , 0x9C , 0xCB , 0xD4 , 0x2B , 0x6A , 0x4F , 0xC6 , 0xCC , 0xCF , 0x90 , 0xA7 , 0xB9 , 0x98 , 0x47 ,
0xFD , 0xFA , 0x4C , 0x6C , 0x6F , 0x81 , 0x87 , 0x3B , 0xCA , 0xB8 , 0x50 , 0xF6 , 0x3E , 0x39 , 0x5D , 0x4D ,
0x97 , 0x3F , 0x0F , 0x35 , 0x39 , 0x53 , 0xFB , 0xFA , 0xCD , 0xAB , 0xA8 , 0x7A , 0x62 , 0x9A , 0x3F , 0xF2 ,
0x09 , 0x27 , 0x96 , 0x3F , 0x07 , 0x9A , 0x91 , 0xF7 , 0x16 , 0xBF , 0xC6 , 0x3A , 0x82 , 0x5A , 0x4B , 0xCF ,
0x49 , 0x50 , 0x95 , 0x8C , 0x55 , 0x80 , 0x7E , 0x39 , 0xB1 , 0x48 , 0x05 , 0x1E , 0x21 , 0xC7 , 0x24 , 0x4F
} ;
static const std : : vector < sRsaKeyForGeneration > kProdNcaHeaderSign0Modulus =
{
{
0x00 ,
{ 0xBF , 0xBE , 0x40 , 0x6C , 0xF4 , 0xA7 , 0x80 , 0xE9 , 0xF0 , 0x7D , 0x0C , 0x99 , 0x61 , 0x1D , 0x77 , 0x2F ,
0x96 , 0xBC , 0x4B , 0x9E , 0x58 , 0x38 , 0x1B , 0x03 , 0xAB , 0xB1 , 0x75 , 0x49 , 0x9F , 0x2B , 0x4D , 0x58 ,
0x34 , 0xB0 , 0x05 , 0xA3 , 0x75 , 0x22 , 0xBE , 0x1A , 0x3F , 0x03 , 0x73 , 0xAC , 0x70 , 0x68 , 0xD1 , 0x16 ,
0xB9 , 0x04 , 0x46 , 0x5E , 0xB7 , 0x07 , 0x91 , 0x2F , 0x07 , 0x8B , 0x26 , 0xDE , 0xF6 , 0x00 , 0x07 , 0xB2 ,
0xB4 , 0x51 , 0xF8 , 0x0D , 0x0A , 0x5E , 0x58 , 0xAD , 0xEB , 0xBC , 0x9A , 0xD6 , 0x49 , 0xB9 , 0x64 , 0xEF ,
0xA7 , 0x82 , 0xB5 , 0xCF , 0x6D , 0x70 , 0x13 , 0xB0 , 0x0F , 0x85 , 0xF6 , 0xA9 , 0x08 , 0xAA , 0x4D , 0x67 ,
0x66 , 0x87 , 0xFA , 0x89 , 0xFF , 0x75 , 0x90 , 0x18 , 0x1E , 0x6B , 0x3D , 0xE9 , 0x8A , 0x68 , 0xC9 , 0x26 ,
0x04 , 0xD9 , 0x80 , 0xCE , 0x3F , 0x5E , 0x92 , 0xCE , 0x01 , 0xFF , 0x06 , 0x3B , 0xF2 , 0xC1 , 0xA9 , 0x0C ,
0xCE , 0x02 , 0x6F , 0x16 , 0xBC , 0x92 , 0x42 , 0x0A , 0x41 , 0x64 , 0xCD , 0x52 , 0xB6 , 0x34 , 0x4D , 0xAE ,
0xC0 , 0x2E , 0xDE , 0xA4 , 0xDF , 0x27 , 0x68 , 0x3C , 0xC1 , 0xA0 , 0x60 , 0xAD , 0x43 , 0xF3 , 0xFC , 0x86 ,
0xC1 , 0x3E , 0x6C , 0x46 , 0xF7 , 0x7C , 0x29 , 0x9F , 0xFA , 0xFD , 0xF0 , 0xE3 , 0xCE , 0x64 , 0xE7 , 0x35 ,
0xF2 , 0xF6 , 0x56 , 0x56 , 0x6F , 0x6D , 0xF1 , 0xE2 , 0x42 , 0xB0 , 0x83 , 0x40 , 0xA5 , 0xC3 , 0x20 , 0x2B ,
0xCC , 0x9A , 0xAE , 0xCA , 0xED , 0x4D , 0x70 , 0x30 , 0xA8 , 0x70 , 0x1C , 0x70 , 0xFD , 0x13 , 0x63 , 0x29 ,
0x02 , 0x79 , 0xEA , 0xD2 , 0xA7 , 0xAF , 0x35 , 0x28 , 0x32 , 0x1C , 0x7B , 0xE6 , 0x2F , 0x1A , 0xAA , 0x40 ,
0x7E , 0x32 , 0x8C , 0x27 , 0x42 , 0xFE , 0x82 , 0x78 , 0xEC , 0x0D , 0xEB , 0xE6 , 0x83 , 0x4B , 0x6D , 0x81 ,
0x04 , 0x40 , 0x1A , 0x9E , 0x9A , 0x67 , 0xF6 , 0x72 , 0x29 , 0xFA , 0x04 , 0xF0 , 0x9D , 0xE4 , 0xF4 , 0x03 , }
} ,
{
0x01 ,
{ 0xAD , 0xE3 , 0xE1 , 0xFA , 0x04 , 0x35 , 0xE5 , 0xB6 , 0xDD , 0x49 , 0xEA , 0x89 , 0x29 , 0xB1 , 0xFF , 0xB6 ,
2021-10-02 04:11:37 +00:00
0x43 , 0xDF , 0xCA , 0x96 , 0xA0 , 0x4A , 0x13 , 0xDF , 0x43 , 0xD9 , 0x94 , 0x97 , 0x96 , 0x43 , 0x65 , 0x48 ,
0x70 , 0x58 , 0x33 , 0xA2 , 0x7D , 0x35 , 0x7B , 0x96 , 0x74 , 0x5E , 0x0B , 0x5C , 0x32 , 0x18 , 0x14 , 0x24 ,
0xC2 , 0x58 , 0xB3 , 0x6C , 0x22 , 0x7A , 0xA1 , 0xB7 , 0xCB , 0x90 , 0xA7 , 0xA3 , 0xF9 , 0x7D , 0x45 , 0x16 ,
0xA5 , 0xC8 , 0xED , 0x8F , 0xAD , 0x39 , 0x5E , 0x9E , 0x4B , 0x51 , 0x68 , 0x7D , 0xF8 , 0x0C , 0x35 , 0xC6 ,
0x3F , 0x91 , 0xAE , 0x44 , 0xA5 , 0x92 , 0x30 , 0x0D , 0x46 , 0xF8 , 0x40 , 0xFF , 0xD0 , 0xFF , 0x06 , 0xD2 ,
0x1C , 0x7F , 0x96 , 0x18 , 0xDC , 0xB7 , 0x1D , 0x66 , 0x3E , 0xD1 , 0x73 , 0xBC , 0x15 , 0x8A , 0x2F , 0x94 ,
0xF3 , 0x00 , 0xC1 , 0x83 , 0xF1 , 0xCD , 0xD7 , 0x81 , 0x88 , 0xAB , 0xDF , 0x8C , 0xEF , 0x97 , 0xDD , 0x1B ,
0x17 , 0x5F , 0x58 , 0xF6 , 0x9A , 0xE9 , 0xE8 , 0xC2 , 0x2F , 0x38 , 0x15 , 0xF5 , 0x21 , 0x07 , 0xF8 , 0x37 ,
0x90 , 0x5D , 0x2E , 0x02 , 0x40 , 0x24 , 0x15 , 0x0D , 0x25 , 0xB7 , 0x26 , 0x5D , 0x09 , 0xCC , 0x4C , 0xF4 ,
0xF2 , 0x1B , 0x94 , 0x70 , 0x5A , 0x9E , 0xEE , 0xED , 0x77 , 0x77 , 0xD4 , 0x51 , 0x99 , 0xF5 , 0xDC , 0x76 ,
0x1E , 0xE3 , 0x6C , 0x8C , 0xD1 , 0x12 , 0xD4 , 0x57 , 0xD1 , 0xB6 , 0x83 , 0xE4 , 0xE4 , 0xFE , 0xDA , 0xE9 ,
0xB4 , 0x3B , 0x33 , 0xE5 , 0x37 , 0x8A , 0xDF , 0xB5 , 0x7F , 0x89 , 0xF1 , 0x9B , 0x9E , 0xB0 , 0x15 , 0xB2 ,
0x3A , 0xFE , 0xEA , 0x61 , 0x84 , 0x5B , 0x7D , 0x4B , 0x23 , 0x12 , 0x0B , 0x83 , 0x12 , 0xF2 , 0x22 , 0x6B ,
0xB9 , 0x22 , 0x96 , 0x4B , 0x26 , 0x0B , 0x63 , 0x5E , 0x96 , 0x57 , 0x52 , 0xA3 , 0x67 , 0x64 , 0x22 , 0xCA ,
0xD0 , 0x56 , 0x3E , 0x74 , 0xB5 , 0x98 , 0x1F , 0x0D , 0xF8 , 0xB3 , 0x34 , 0xE6 , 0x98 , 0x68 , 0x5A , 0xAD , }
2021-10-02 04:08:34 +00:00
} ,
} ;
static const std : : vector < sRsaKeyForGeneration > kProdAcidSignModulus =
{
{
0x00 ,
{ 0xDD , 0xC8 , 0xDD , 0xF2 , 0x4E , 0x6D , 0xF0 , 0xCA , 0x9E , 0xC7 , 0x5D , 0xC7 , 0x7B , 0xAD , 0xFE , 0x7D ,
2021-10-02 04:10:23 +00:00
0x23 , 0x89 , 0x69 , 0xB6 , 0xF2 , 0x06 , 0xA2 , 0x02 , 0x88 , 0xE1 , 0x55 , 0x91 , 0xAB , 0xCB , 0x4D , 0x50 ,
0x2E , 0xFC , 0x9D , 0x94 , 0x76 , 0xD6 , 0x4C , 0xD8 , 0xFF , 0x10 , 0xFA , 0x5E , 0x93 , 0x0A , 0xB4 , 0x57 ,
0xAC , 0x51 , 0xC7 , 0x16 , 0x66 , 0xF4 , 0x1A , 0x54 , 0xC2 , 0xC5 , 0x04 , 0x3D , 0x1B , 0xFE , 0x30 , 0x20 ,
0x8A , 0xAC , 0x6F , 0x6F , 0xF5 , 0xC7 , 0xB6 , 0x68 , 0xB8 , 0xC9 , 0x40 , 0x6B , 0x42 , 0xAD , 0x11 , 0x21 ,
0xE7 , 0x8B , 0xE9 , 0x75 , 0x01 , 0x86 , 0xE4 , 0x48 , 0x9B , 0x0A , 0x0A , 0xF8 , 0x7F , 0xE8 , 0x87 , 0xF2 ,
0x82 , 0x01 , 0xE6 , 0xA3 , 0x0F , 0xE4 , 0x66 , 0xAE , 0x83 , 0x3F , 0x4E , 0x9F , 0x5E , 0x01 , 0x30 , 0xA4 ,
0x00 , 0xB9 , 0x9A , 0xAE , 0x5F , 0x03 , 0xCC , 0x18 , 0x60 , 0xE5 , 0xEF , 0x3B , 0x5E , 0x15 , 0x16 , 0xFE ,
0x1C , 0x82 , 0x78 , 0xB5 , 0x2F , 0x47 , 0x7C , 0x06 , 0x66 , 0x88 , 0x5D , 0x35 , 0xA2 , 0x67 , 0x20 , 0x10 ,
0xE7 , 0x6C , 0x43 , 0x68 , 0xD3 , 0xE4 , 0x5A , 0x68 , 0x2A , 0x5A , 0xE2 , 0x6D , 0x73 , 0xB0 , 0x31 , 0x53 ,
0x1C , 0x20 , 0x09 , 0x44 , 0xF5 , 0x1A , 0x9D , 0x22 , 0xBE , 0x12 , 0xA1 , 0x77 , 0x11 , 0xE2 , 0xA1 , 0xCD ,
0x40 , 0x9A , 0xA2 , 0x8B , 0x60 , 0x9B , 0xEF , 0xA0 , 0xD3 , 0x48 , 0x63 , 0xA2 , 0xF8 , 0xA3 , 0x2C , 0x08 ,
0x56 , 0x52 , 0x2E , 0x60 , 0x19 , 0x67 , 0x5A , 0xA7 , 0x9F , 0xDC , 0x3F , 0x3F , 0x69 , 0x2B , 0x31 , 0x6A ,
0xB7 , 0x88 , 0x4A , 0x14 , 0x84 , 0x80 , 0x33 , 0x3C , 0x9D , 0x44 , 0xB7 , 0x3F , 0x4C , 0xE1 , 0x75 , 0xEA ,
0x37 , 0xEA , 0xE8 , 0x1E , 0x7C , 0x77 , 0xB7 , 0xC6 , 0x1A , 0xA2 , 0xF0 , 0x9F , 0x10 , 0x61 , 0xCD , 0x7B ,
0x5B , 0x32 , 0x4C , 0x37 , 0xEF , 0xB1 , 0x71 , 0x68 , 0x53 , 0x0A , 0xED , 0x51 , 0x7D , 0x35 , 0x22 , 0xFD , }
2021-10-02 04:08:34 +00:00
} ,
{
0x01 ,
{ 0xE7 , 0xAA , 0x25 , 0xC8 , 0x01 , 0xA5 , 0x14 , 0x6B , 0x01 , 0x60 , 0x3E , 0xD9 , 0x96 , 0x5A , 0xBF , 0x90 ,
2021-10-02 04:10:23 +00:00
0xAC , 0xA7 , 0xFD , 0x9B , 0x5B , 0xBD , 0x8A , 0x26 , 0xB0 , 0xCB , 0x20 , 0x28 , 0x9A , 0x72 , 0x12 , 0xF5 ,
0x20 , 0x65 , 0xB3 , 0xB9 , 0x84 , 0x58 , 0x1F , 0x27 , 0xBC , 0x7C , 0xA2 , 0xC9 , 0x9E , 0x18 , 0x95 , 0xCF ,
0xC2 , 0x73 , 0x2E , 0x74 , 0x8C , 0x66 , 0xE5 , 0x9E , 0x79 , 0x2B , 0xB8 , 0x07 , 0x0C , 0xB0 , 0x4E , 0x8E ,
0xAB , 0x85 , 0x21 , 0x42 , 0xC4 , 0xC5 , 0x6D , 0x88 , 0x9C , 0xDB , 0x15 , 0x95 , 0x3F , 0x80 , 0xDB , 0x7A ,
0x9A , 0x7D , 0x41 , 0x56 , 0x25 , 0x17 , 0x18 , 0x42 , 0x4D , 0x8C , 0xAC , 0xA5 , 0x7B , 0xDB , 0x42 , 0x5D ,
0x59 , 0x35 , 0x45 , 0x5D , 0x8A , 0x02 , 0xB5 , 0x70 , 0xC0 , 0x72 , 0x35 , 0x46 , 0xD0 , 0x1D , 0x60 , 0x01 ,
0x4A , 0xCC , 0x1C , 0x46 , 0xD3 , 0xD6 , 0x35 , 0x52 , 0xD6 , 0xE1 , 0xF8 , 0x3B , 0x5D , 0xEA , 0xDD , 0xB8 ,
0xFE , 0x7D , 0x50 , 0xCB , 0x35 , 0x23 , 0x67 , 0x8B , 0xB6 , 0xE4 , 0x74 , 0xD2 , 0x60 , 0xFC , 0xFD , 0x43 ,
0xBF , 0x91 , 0x08 , 0x81 , 0xC5 , 0x4F , 0x5D , 0x16 , 0x9A , 0xC4 , 0x9A , 0xC6 , 0xF6 , 0xF3 , 0xE1 , 0xF6 ,
0x5C , 0x07 , 0xAA , 0x71 , 0x6C , 0x13 , 0xA4 , 0xB1 , 0xB3 , 0x66 , 0xBF , 0x90 , 0x4C , 0x3D , 0xA2 , 0xC4 ,
0x0B , 0xB8 , 0x3D , 0x7A , 0x8C , 0x19 , 0xFA , 0xFF , 0x6B , 0xB9 , 0x1F , 0x02 , 0xCC , 0xB6 , 0xD3 , 0x0C ,
0x7D , 0x19 , 0x1F , 0x47 , 0xF9 , 0xC7 , 0x40 , 0x01 , 0xFA , 0x46 , 0xEA , 0x0B , 0xD4 , 0x02 , 0xE0 , 0x3D ,
0x30 , 0x9A , 0x1A , 0x0F , 0xEA , 0xA7 , 0x66 , 0x55 , 0xF7 , 0xCB , 0x28 , 0xE2 , 0xBB , 0x99 , 0xE4 , 0x83 ,
0xC3 , 0x43 , 0x03 , 0xEE , 0xDC , 0x1F , 0x02 , 0x23 , 0xDD , 0xD1 , 0x2D , 0x39 , 0xA4 , 0x65 , 0x75 , 0x03 ,
0xEF , 0x37 , 0x9C , 0x06 , 0xD6 , 0xFA , 0xA1 , 0x15 , 0xF0 , 0xDB , 0x17 , 0x47 , 0x26 , 0x4F , 0x49 , 0x03 }
2021-10-02 04:08:34 +00:00
} ,
} ;
static const nn : : hac : : detail : : rsa2048_block_t kDevPackage2HeaderModulus = {
0xB3 , 0x65 , 0x54 , 0xFB , 0x0A , 0xB0 , 0x1E , 0x85 , 0xA7 , 0xF6 , 0xCF , 0x91 , 0x8E , 0xBA , 0x96 , 0x99 ,
0x0D , 0x8B , 0x91 , 0x69 , 0x2A , 0xEE , 0x01 , 0x20 , 0x4F , 0x34 , 0x5C , 0x2C , 0x4F , 0x4E , 0x37 , 0xC7 ,
0xF1 , 0x0B , 0xD4 , 0xCD , 0xA1 , 0x7F , 0x93 , 0xF1 , 0x33 , 0x59 , 0xCE , 0xB1 , 0xE9 , 0xDD , 0x26 , 0xE6 ,
0xF3 , 0xBB , 0x77 , 0x87 , 0x46 , 0x7A , 0xD6 , 0x4E , 0x47 , 0x4A , 0xD1 , 0x41 , 0xB7 , 0x79 , 0x4A , 0x38 ,
0x06 , 0x6E , 0xCF , 0x61 , 0x8F , 0xCD , 0xC1 , 0x40 , 0x0B , 0xFA , 0x26 , 0xDC , 0xC0 , 0x34 , 0x51 , 0x83 ,
0xD9 , 0x3B , 0x11 , 0x54 , 0x3B , 0x96 , 0x27 , 0x32 , 0x9A , 0x95 , 0xBE , 0x1E , 0x68 , 0x11 , 0x50 , 0xA0 ,
0x6B , 0x10 , 0xA8 , 0x83 , 0x8B , 0xF5 , 0xFC , 0xBC , 0x90 , 0x84 , 0x7A , 0x5A , 0x5C , 0x43 , 0x52 , 0xE6 ,
0xC8 , 0x26 , 0xE9 , 0xFE , 0x06 , 0xA0 , 0x8B , 0x53 , 0x0F , 0xAF , 0x1E , 0xC4 , 0x1C , 0x0B , 0xCF , 0x50 ,
0x1A , 0xA4 , 0xF3 , 0x5C , 0xFB , 0xF0 , 0x97 , 0xE4 , 0xDE , 0x32 , 0x0A , 0x9F , 0xE3 , 0x5A , 0xAA , 0xB7 ,
0x44 , 0x7F , 0x5C , 0x33 , 0x60 , 0xB9 , 0x0F , 0x22 , 0x2D , 0x33 , 0x2A , 0xE9 , 0x69 , 0x79 , 0x31 , 0x42 ,
0x8F , 0xE4 , 0x3A , 0x13 , 0x8B , 0xE7 , 0x26 , 0xBD , 0x08 , 0x87 , 0x6C , 0xA6 , 0xF2 , 0x73 , 0xF6 , 0x8E ,
0xA7 , 0xF2 , 0xFE , 0xFB , 0x6C , 0x28 , 0x66 , 0x0D , 0xBD , 0xD7 , 0xEB , 0x42 , 0xA8 , 0x78 , 0xE6 , 0xB8 ,
0x6B , 0xAE , 0xC7 , 0xA9 , 0xE2 , 0x40 , 0x6E , 0x89 , 0x20 , 0x82 , 0x25 , 0x8E , 0x3C , 0x6A , 0x60 , 0xD7 ,
0xF3 , 0x56 , 0x8E , 0xEC , 0x8D , 0x51 , 0x8A , 0x63 , 0x3C , 0x04 , 0x78 , 0x23 , 0x0E , 0x90 , 0x0C , 0xB4 ,
0xE7 , 0x86 , 0x3B , 0x4F , 0x8E , 0x13 , 0x09 , 0x47 , 0x32 , 0x0E , 0x04 , 0xB8 , 0x4D , 0x5B , 0xB0 , 0x46 ,
0x71 , 0xB0 , 0x5C , 0xF4 , 0xAD , 0x63 , 0x4F , 0xC5 , 0xE2 , 0xAC , 0x1E , 0xC4 , 0x33 , 0x96 , 0x09 , 0x7B
} ;
static const std : : vector < sRsaKeyForGeneration > kDevNcaHeaderSign0Modulus =
{
{
0x00 ,
{ 0xD8 , 0xF1 , 0x18 , 0xEF , 0x32 , 0x72 , 0x4C , 0xA7 , 0x47 , 0x4C , 0xB9 , 0xEA , 0xB3 , 0x04 , 0xA8 , 0xA4 ,
0xAC , 0x99 , 0x08 , 0x08 , 0x04 , 0xBF , 0x68 , 0x57 , 0xB8 , 0x43 , 0x94 , 0x2B , 0xC7 , 0xB9 , 0x66 , 0x49 ,
0x85 , 0xE5 , 0x8A , 0x9B , 0xC1 , 0x00 , 0x9A , 0x6A , 0x8D , 0xD0 , 0xEF , 0xCE , 0xFF , 0x86 , 0xC8 , 0x5C ,
0x5D , 0xE9 , 0x53 , 0x7B , 0x19 , 0x2A , 0xA8 , 0xC0 , 0x22 , 0xD1 , 0xF3 , 0x22 , 0x0A , 0x50 , 0xF2 , 0x2B ,
0x65 , 0x05 , 0x1B , 0x9E , 0xEC , 0x61 , 0xB5 , 0x63 , 0xA3 , 0x6F , 0x3B , 0xBA , 0x63 , 0x3A , 0x53 , 0xF4 ,
0x49 , 0x2F , 0xCF , 0x03 , 0xCC , 0xD7 , 0x50 , 0x82 , 0x1B , 0x29 , 0x4F , 0x08 , 0xDE , 0x1B , 0x6D , 0x47 ,
0x4F , 0xA8 , 0xB6 , 0x6A , 0x26 , 0xA0 , 0x83 , 0x3F , 0x1A , 0xAF , 0x83 , 0x8F , 0x0E , 0x17 , 0x3F , 0xFE ,
0x44 , 0x1C , 0x56 , 0x94 , 0x2E , 0x49 , 0x83 , 0x83 , 0x03 , 0xE9 , 0xB6 , 0xAD , 0xD5 , 0xDE , 0xE3 , 0x2D ,
0xA1 , 0xD9 , 0x66 , 0x20 , 0x5D , 0x1F , 0x5E , 0x96 , 0x5D , 0x5B , 0x55 , 0x0D , 0xD4 , 0xB4 , 0x77 , 0x6E ,
0xAE , 0x1B , 0x69 , 0xF3 , 0xA6 , 0x61 , 0x0E , 0x51 , 0x62 , 0x39 , 0x28 , 0x63 , 0x75 , 0x76 , 0xBF , 0xB0 ,
0xD2 , 0x22 , 0xEF , 0x98 , 0x25 , 0x02 , 0x05 , 0xC0 , 0xD7 , 0x6A , 0x06 , 0x2C , 0xA5 , 0xD8 , 0x5A , 0x9D ,
0x7A , 0xA4 , 0x21 , 0x55 , 0x9F , 0xF9 , 0x3E , 0xBF , 0x16 , 0xF6 , 0x07 , 0xC2 , 0xB9 , 0x6E , 0x87 , 0x9E ,
0xB5 , 0x1C , 0xBE , 0x97 , 0xFA , 0x82 , 0x7E , 0xED , 0x30 , 0xD4 , 0x66 , 0x3F , 0xDE , 0xD8 , 0x1B , 0x4B ,
0x15 , 0xD9 , 0xFB , 0x2F , 0x50 , 0xF0 , 0x9D , 0x1D , 0x52 , 0x4C , 0x1C , 0x4D , 0x8D , 0xAE , 0x85 , 0x1E ,
0xEA , 0x7F , 0x86 , 0xF3 , 0x0B , 0x7B , 0x87 , 0x81 , 0x98 , 0x23 , 0x80 , 0x63 , 0x4F , 0x2F , 0xB0 , 0x62 ,
0xCC , 0x6E , 0xD2 , 0x46 , 0x13 , 0x65 , 0x2B , 0xD6 , 0x44 , 0x33 , 0x59 , 0xB5 , 0x8F , 0xB9 , 0x4A , 0xA9 , }
} ,
{
0x01 ,
{ 0x9A , 0xBC , 0x88 , 0xBD , 0x0A , 0xBE , 0xD7 , 0x0C , 0x9B , 0x42 , 0x75 , 0x65 , 0x38 , 0x5E , 0xD1 , 0x01 ,
0xCD , 0x12 , 0xAE , 0xEA , 0xE9 , 0x4B , 0xDB , 0xB4 , 0x5E , 0x36 , 0x10 , 0x96 , 0xDA , 0x3D , 0x2E , 0x66 ,
0xD3 , 0x99 , 0x13 , 0x8A , 0xBE , 0x67 , 0x41 , 0xC8 , 0x93 , 0xD9 , 0x3E , 0x42 , 0xCE , 0x34 , 0xCE , 0x96 ,
0xFA , 0x0B , 0x23 , 0xCC , 0x2C , 0xDF , 0x07 , 0x3F , 0x3B , 0x24 , 0x4B , 0x12 , 0x67 , 0x3A , 0x29 , 0x36 ,
0xA3 , 0xAA , 0x06 , 0xF0 , 0x65 , 0xA5 , 0x85 , 0xBA , 0xFD , 0x12 , 0xEC , 0xF1 , 0x60 , 0x67 , 0xF0 , 0x8F ,
0xD3 , 0x5B , 0x01 , 0x1B , 0x1E , 0x84 , 0xA3 , 0x5C , 0x65 , 0x36 , 0xF9 , 0x23 , 0x7E , 0xF3 , 0x26 , 0x38 ,
0x64 , 0x98 , 0xBA , 0xE4 , 0x19 , 0x91 , 0x4C , 0x02 , 0xCF , 0xC9 , 0x6D , 0x86 , 0xEC , 0x1D , 0x41 , 0x69 ,
0xDD , 0x56 , 0xEA , 0x5C , 0xA3 , 0x2A , 0x58 , 0xB4 , 0x39 , 0xCC , 0x40 , 0x31 , 0xFD , 0xFB , 0x42 , 0x74 ,
0xF8 , 0xEC , 0xEA , 0x00 , 0xF0 , 0xD9 , 0x28 , 0xEA , 0xFA , 0x2D , 0x00 , 0xE1 , 0x43 , 0x53 , 0xC6 , 0x32 ,
0xF4 , 0xA2 , 0x07 , 0xD4 , 0x5F , 0xD4 , 0xCB , 0xAC , 0xCA , 0xFF , 0xDF , 0x84 , 0xD2 , 0x86 , 0x14 , 0x3C ,
0xDE , 0x22 , 0x75 , 0xA5 , 0x73 , 0xFF , 0x68 , 0x07 , 0x4A , 0xF9 , 0x7C , 0x2C , 0xCC , 0xDE , 0x45 , 0xB6 ,
0x54 , 0x82 , 0x90 , 0x36 , 0x1F , 0x2C , 0x51 , 0x96 , 0xC5 , 0x0A , 0x53 , 0x5B , 0xF0 , 0x8B , 0x4A , 0xAA ,
0x3B , 0x68 , 0x97 , 0x19 , 0x17 , 0x1F , 0x01 , 0xB8 , 0xED , 0xB9 , 0x9A , 0x5E , 0x08 , 0xC5 , 0x20 , 0x1E ,
0x6A , 0x09 , 0xF0 , 0xE9 , 0x73 , 0xA3 , 0xBE , 0x10 , 0x06 , 0x02 , 0xE9 , 0xFB , 0x85 , 0xFA , 0x5F , 0x01 ,
0xAC , 0x60 , 0xE0 , 0xED , 0x7D , 0xB9 , 0x49 , 0xA8 , 0x9E , 0x98 , 0x7D , 0x91 , 0x40 , 0x05 , 0xCF , 0xF9 ,
0x1A , 0xFC , 0x40 , 0x22 , 0xA8 , 0x96 , 0x5B , 0xB0 , 0xDC , 0x7A , 0xF5 , 0xB7 , 0xE9 , 0x91 , 0x4C , 0x49 , }
} ,
} ;
static const std : : vector < sRsaKeyForGeneration > kDevAcidSignModulus =
{
{
0x00 ,
{ 0xD6 , 0x34 , 0xA5 , 0x78 , 0x6C , 0x68 , 0xCE , 0x5A , 0xC2 , 0x37 , 0x17 , 0xF3 , 0x82 , 0x45 , 0xC6 , 0x89 ,
0xE1 , 0x2D , 0x06 , 0x67 , 0xBF , 0xB4 , 0x06 , 0x19 , 0x55 , 0x6B , 0x27 , 0x66 , 0x0C , 0xA4 , 0xB5 , 0x87 ,
0x81 , 0x25 , 0xF4 , 0x30 , 0xBC , 0x53 , 0x08 , 0x68 , 0xA2 , 0x48 , 0x49 , 0x8C , 0x3F , 0x38 , 0x40 , 0x9C ,
0xC4 , 0x26 , 0xF4 , 0x79 , 0xE2 , 0xA1 , 0x85 , 0xF5 , 0x5C , 0x7F , 0x58 , 0xBA , 0xA6 , 0x1C , 0xA0 , 0x8B ,
0x84 , 0x16 , 0x14 , 0x6F , 0x85 , 0xD9 , 0x7C , 0xE1 , 0x3C , 0x67 , 0x22 , 0x1E , 0xFB , 0xD8 , 0xA7 , 0xA5 ,
0x9A , 0xBF , 0xEC , 0x0E , 0xCF , 0x96 , 0x7E , 0x85 , 0xC2 , 0x1D , 0x49 , 0x5D , 0x54 , 0x26 , 0xCB , 0x32 ,
0x7C , 0xF6 , 0xBB , 0x58 , 0x03 , 0x80 , 0x2B , 0x5D , 0xF7 , 0xFB , 0xD1 , 0x9D , 0xC7 , 0xC6 , 0x2E , 0x53 ,
0xC0 , 0x6F , 0x39 , 0x2C , 0x1F , 0xA9 , 0x92 , 0xF2 , 0x4D , 0x7D , 0x4E , 0x74 , 0xFF , 0xE4 , 0xEF , 0xE4 ,
0x7C , 0x3D , 0x34 , 0x2A , 0x71 , 0xA4 , 0x97 , 0x59 , 0xFF , 0x4F , 0xA2 , 0xF4 , 0x66 , 0x78 , 0xD8 , 0xBA ,
0x99 , 0xE3 , 0xE6 , 0xDB , 0x54 , 0xB9 , 0xE9 , 0x54 , 0xA1 , 0x70 , 0xFC , 0x05 , 0x1F , 0x11 , 0x67 , 0x4B ,
0x26 , 0x8C , 0x0C , 0x3E , 0x03 , 0xD2 , 0xA3 , 0x55 , 0x5C , 0x7D , 0xC0 , 0x5D , 0x9D , 0xFF , 0x13 , 0x2F ,
0xFD , 0x19 , 0xBF , 0xED , 0x44 , 0xC3 , 0x8C , 0xA7 , 0x28 , 0xCB , 0xE5 , 0xE0 , 0xB1 , 0xA7 , 0x9C , 0x33 ,
0x8D , 0xB8 , 0x6E , 0xDE , 0x87 , 0x18 , 0x22 , 0x60 , 0xC4 , 0xAE , 0xF2 , 0x87 , 0x9F , 0xCE , 0x09 , 0x5C ,
0xB5 , 0x99 , 0xA5 , 0x9F , 0x49 , 0xF2 , 0xD7 , 0x58 , 0xFA , 0xF9 , 0xC0 , 0x25 , 0x7D , 0xD6 , 0xCB , 0xF3 ,
0xD8 , 0x6C , 0xA2 , 0x69 , 0x91 , 0x68 , 0x73 , 0xB1 , 0x94 , 0x6F , 0xA3 , 0xF3 , 0xB9 , 0x7D , 0xF8 , 0xE0 ,
0x72 , 0x9E , 0x93 , 0x7B , 0x7A , 0xA2 , 0x57 , 0x60 , 0xB7 , 0x5B , 0xA9 , 0x84 , 0xAE , 0x64 , 0x88 , 0x69 }
} ,
{
0x01 ,
{ 0xBC , 0xA5 , 0x6A , 0x7E , 0xEA , 0x38 , 0x34 , 0x62 , 0xA6 , 0x10 , 0x18 , 0x3C , 0xE1 , 0x63 , 0x7B , 0xF0 ,
0xD3 , 0x08 , 0x8C , 0xF5 , 0xC5 , 0xC4 , 0xC7 , 0x93 , 0xE9 , 0xD9 , 0xE6 , 0x32 , 0xF3 , 0xA0 , 0xF6 , 0x6E ,
0x8A , 0x98 , 0x76 , 0x47 , 0x33 , 0x47 , 0x65 , 0x02 , 0x70 , 0xDC , 0x86 , 0x5F , 0x3D , 0x61 , 0x5A , 0x70 ,
0xBC , 0x5A , 0xCA , 0xCA , 0x50 , 0xAD , 0x61 , 0x7E , 0xC9 , 0xEC , 0x27 , 0xFF , 0xE8 , 0x64 , 0x42 , 0x9A ,
0xEE , 0xBE , 0xC3 , 0xD1 , 0x0B , 0xC0 , 0xE9 , 0xBF , 0x83 , 0x8D , 0xC0 , 0x0C , 0xD8 , 0x00 , 0x5B , 0x76 ,
0x90 , 0xD2 , 0x4B , 0x30 , 0x84 , 0x35 , 0x8B , 0x1E , 0x20 , 0xB7 , 0xE4 , 0xDC , 0x63 , 0xE5 , 0xDF , 0xCD ,
0x00 , 0x5F , 0x81 , 0x5F , 0x67 , 0xC5 , 0x8B , 0xDF , 0xFC , 0xE1 , 0x37 , 0x5F , 0x07 , 0xD9 , 0xDE , 0x4F ,
0xE6 , 0x7B , 0xF1 , 0xFB , 0xA1 , 0x5A , 0x71 , 0x40 , 0xFE , 0xBA , 0x1E , 0xAE , 0x13 , 0x22 , 0xD2 , 0xFE ,
0x37 , 0xA2 , 0xB6 , 0x8B , 0xAB , 0xEB , 0x84 , 0x81 , 0x4E , 0x7C , 0x1E , 0x02 , 0xD1 , 0xFB , 0xD7 , 0x5D ,
0x11 , 0x84 , 0x64 , 0xD2 , 0x4D , 0xBB , 0x50 , 0x00 , 0x67 , 0x54 , 0xE2 , 0x77 , 0x89 , 0xBA , 0x0B , 0xE7 ,
0x05 , 0x57 , 0x9A , 0x22 , 0x5A , 0xEC , 0x76 , 0x1C , 0xFD , 0xE8 , 0xA8 , 0x18 , 0x16 , 0x41 , 0x65 , 0x03 ,
0xFA , 0xC4 , 0xA6 , 0x31 , 0x5C , 0x1A , 0x7F , 0xAB , 0x11 , 0xC8 , 0x4A , 0x99 , 0xB9 , 0xE6 , 0xCF , 0x62 ,
0x21 , 0xA6 , 0x72 , 0x47 , 0xDB , 0xBA , 0x96 , 0x26 , 0x4E , 0x2E , 0xD4 , 0x8C , 0x46 , 0xD6 , 0xA7 , 0x1A ,
0x6C , 0x32 , 0xA7 , 0xDF , 0x85 , 0x1C , 0x03 , 0xC3 , 0x6D , 0xA9 , 0xE9 , 0x68 , 0xF4 , 0x17 , 0x1E , 0xB2 ,
0x70 , 0x2A , 0xA1 , 0xE5 , 0xE1 , 0xF3 , 0x8F , 0x6F , 0x63 , 0xAC , 0xEB , 0x72 , 0x0B , 0x4C , 0x4A , 0x36 ,
0x3C , 0x60 , 0x91 , 0x9F , 0x6E , 0x1C , 0x71 , 0xEA , 0xD0 , 0x78 , 0x78 , 0xA0 , 0x2E , 0xC6 , 0x32 , 0x6B }
} ,
} ;
if ( isDev )
{
if ( xci_header_sign_key . isNull ( ) )
xci_header_sign_key = tc : : crypto : : RsaPublicKey ( kXciHeaderSignModulus . data ( ) , kXciHeaderSignModulus . size ( ) ) ;
if ( xci_cert_sign_key . isNull ( ) )
xci_cert_sign_key = tc : : crypto : : RsaPublicKey ( kXciCertSignModulus . data ( ) , kXciCertSignModulus . size ( ) ) ;
if ( pkg2_sign_key . isNull ( ) )
pkg2_sign_key = tc : : crypto : : RsaPublicKey ( kDevPackage2HeaderModulus . data ( ) , kDevPackage2HeaderModulus . size ( ) ) ;
for ( auto itr = kDevNcaHeaderSign0Modulus . begin ( ) ; itr ! = kDevNcaHeaderSign0Modulus . end ( ) ; itr + + )
{
if ( nca_header_sign0_key . find ( itr - > generation ) = = nca_header_sign0_key . end ( ) )
nca_header_sign0_key [ itr - > generation ] = tc : : crypto : : RsaPublicKey ( itr - > modulus . data ( ) , itr - > modulus . size ( ) ) ;
}
for ( auto itr = kDevAcidSignModulus . begin ( ) ; itr ! = kDevAcidSignModulus . end ( ) ; itr + + )
{
if ( acid_sign_key . find ( itr - > generation ) = = acid_sign_key . end ( ) )
acid_sign_key [ itr - > generation ] = tc : : crypto : : RsaPublicKey ( itr - > modulus . data ( ) , itr - > modulus . size ( ) ) ;
}
}
else
{
if ( xci_header_sign_key . isNull ( ) )
xci_header_sign_key = tc : : crypto : : RsaPublicKey ( kXciHeaderSignModulus . data ( ) , kXciHeaderSignModulus . size ( ) ) ;
if ( xci_cert_sign_key . isNull ( ) )
xci_cert_sign_key = tc : : crypto : : RsaPublicKey ( kXciCertSignModulus . data ( ) , kXciCertSignModulus . size ( ) ) ;
if ( pkg2_sign_key . isNull ( ) )
pkg2_sign_key = tc : : crypto : : RsaPublicKey ( kProdPackage2HeaderModulus . data ( ) , kProdPackage2HeaderModulus . size ( ) ) ;
for ( auto itr = kProdNcaHeaderSign0Modulus . begin ( ) ; itr ! = kProdNcaHeaderSign0Modulus . end ( ) ; itr + + )
{
if ( nca_header_sign0_key . find ( itr - > generation ) = = nca_header_sign0_key . end ( ) )
nca_header_sign0_key [ itr - > generation ] = tc : : crypto : : RsaPublicKey ( itr - > modulus . data ( ) , itr - > modulus . size ( ) ) ;
}
for ( auto itr = kProdAcidSignModulus . begin ( ) ; itr ! = kProdAcidSignModulus . end ( ) ; itr + + )
{
if ( acid_sign_key . find ( itr - > generation ) = = acid_sign_key . end ( ) )
acid_sign_key [ itr - > generation ] = tc : : crypto : : RsaPublicKey ( itr - > modulus . data ( ) , itr - > modulus . size ( ) ) ;
}
}
2021-09-28 11:15:54 +00:00
}