[nstool] Add KeyConfiguration.

This commit is contained in:
jakcron 2018-08-20 19:26:03 +08:00
parent c026aeee92
commit d4435b7559
2 changed files with 549 additions and 0 deletions

View file

@ -0,0 +1,343 @@
#include "KeyConfiguration.h"
#include <fnd/ResourceFileReader.h>
#include <fnd/SimpleTextOutput.h>
#include <nn/hac/AesKeygen.h>
#include <nn/hac/NcaUtils.h>
KeyConfiguration::KeyConfiguration()
{
clearGeneralKeyConfiguration();
clearNcaExternalKeys();
}
void KeyConfiguration::importHactoolGenericKeyfile(const std::string& path)
{
clearGeneralKeyConfiguration();
fnd::ResourceFileReader res;
try
{
res.processFile(path);
}
catch (const fnd::Exception&)
{
throw fnd::Exception(kModuleName, "Failed to open key file: " + path);
}
// internally used sources
fnd::aes::sAes128Key master_key[kMasterKeyNum] = { kNullAesKey };
fnd::aes::sAes128Key package2_key_source = kNullAesKey;
fnd::aes::sAes128Key ticket_titlekek_source = kNullAesKey;
fnd::aes::sAes128Key key_area_key_source[kNcaKeakNum] = { kNullAesKey, kNullAesKey, kNullAesKey };
fnd::aes::sAes128Key aes_kek_generation_source = kNullAesKey;
fnd::aes::sAes128Key aes_key_generation_source = kNullAesKey;
fnd::aes::sAes128Key nca_header_kek_source = kNullAesKey;
fnd::aes::sAesXts128Key nca_header_key_source = kNullAesXtsKey;
fnd::rsa::sRsa4096Key pki_root_sign_key = kNullRsa4096Key;
#define _CONCAT_2_STRINGS(str1, str2) ((str1) + "_" + (str2))
#define _CONCAT_3_STRINGS(str1, str2, str3) _CONCAT_2_STRINGS(_CONCAT_2_STRINGS(str1, str2), str3)
std::string key,val;
fnd::Vec<byte_t> dec_array;
#define _SAVE_KEYDATA(key_name, array, len) \
key = (key_name); \
val = res[key]; \
if (val.empty() == false) { \
fnd::SimpleTextOutput::stringToArray(val, dec_array); \
if (dec_array.size() != len) \
throw fnd::Exception(kModuleName, "Key: \"" + key_name + "\" has incorrect length"); \
memcpy(array, dec_array.data(), len); \
}
for (size_t nameidx = 0; nameidx < kNameVariantNum; nameidx++)
{
// import sources
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kPkg2Base[nameidx], kKeyStr, kSourceStr), package2_key_source.key, 0x10);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kTicketCommonKeyBase[nameidx], kSourceStr), ticket_titlekek_source.key, 0x10);
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kNcaKeyAreaEncKeyBase[nameidx], kNcaKeyAreaKeyIndexStr[0], kSourceStr), key_area_key_source[0].key, 0x10);
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kNcaKeyAreaEncKeyBase[nameidx], kNcaKeyAreaKeyIndexStr[1], kSourceStr), key_area_key_source[1].key, 0x10);
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kNcaKeyAreaEncKeyBase[nameidx], kNcaKeyAreaKeyIndexStr[2], kSourceStr), key_area_key_source[2].key, 0x10);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kKekGenBase[nameidx], kSourceStr), aes_kek_generation_source.key, 0x10);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kKeyGenBase[nameidx], kSourceStr), aes_key_generation_source.key, 0x10);
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kXciHeaderBase[nameidx], kKekStr, kSourceStr), nca_header_kek_source.key, 0x10);
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kXciHeaderBase[nameidx], kKeyStr, kSourceStr), nca_header_key_source.key, 0x20);
// Store Key Variants/Derivatives
for (size_t mkeyidx = 0; mkeyidx < kMasterKeyNum; mkeyidx++)
{
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kMasterBase[nameidx], kKeyStr, kKeyIndex[mkeyidx]), master_key[mkeyidx].key, 0x10);
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kPkg1Base[nameidx], kKeyStr, kKeyIndex[mkeyidx]), mPkg1Key[mkeyidx].key, 0x10);
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kPkg2Base[nameidx], kKeyStr, kKeyIndex[mkeyidx]), mPkg2Key[mkeyidx].key, 0x10);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kTicketCommonKeyBase[nameidx], kKeyIndex[mkeyidx]), mETicketCommonKey[mkeyidx].key, 0x10);
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kNcaKeyAreaEncKeyBase[nameidx], kNcaKeyAreaKeyIndexStr[0], kKeyIndex[mkeyidx]), mNcaKeyAreaEncryptionKey[0][mkeyidx].key, 0x10);
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kNcaKeyAreaEncKeyBase[nameidx], kNcaKeyAreaKeyIndexStr[1], kKeyIndex[mkeyidx]), mNcaKeyAreaEncryptionKey[1][mkeyidx].key, 0x10);
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kNcaKeyAreaEncKeyBase[nameidx], kNcaKeyAreaKeyIndexStr[2], kKeyIndex[mkeyidx]), mNcaKeyAreaEncryptionKey[2][mkeyidx].key, 0x10);
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kNcaKeyAreaEncKeyHwBase[nameidx], kNcaKeyAreaKeyIndexStr[0], kKeyIndex[mkeyidx]), mNcaKeyAreaEncryptionKeyHw[0][mkeyidx].key, 0x10);
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kNcaKeyAreaEncKeyHwBase[nameidx], kNcaKeyAreaKeyIndexStr[1], kKeyIndex[mkeyidx]), mNcaKeyAreaEncryptionKeyHw[1][mkeyidx].key, 0x10);
_SAVE_KEYDATA(_CONCAT_3_STRINGS(kNcaKeyAreaEncKeyHwBase[nameidx], kNcaKeyAreaKeyIndexStr[2], kKeyIndex[mkeyidx]), mNcaKeyAreaEncryptionKeyHw[2][mkeyidx].key, 0x10);
}
// store nca header key
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kNcaHeaderBase[nameidx], kKeyStr), mNcaHeaderKey.key[0], 0x20);
// store xci header key
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kXciHeaderBase[nameidx], kKeyStr), mXciHeaderKey.key, 0x10);
// store rsa keys
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kNcaHeaderBase[nameidx], kRsaKeyPrivate), mNcaHeader0SignKey.priv_exponent, fnd::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kNcaHeaderBase[nameidx], kRsaKeyModulus), mNcaHeader0SignKey.modulus, fnd::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kXciHeaderBase[nameidx], kRsaKeyPrivate), mXciHeaderSignKey.priv_exponent, fnd::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kXciHeaderBase[nameidx], kRsaKeyModulus), mXciHeaderSignKey.modulus, fnd::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kAcidBase[nameidx], kRsaKeyPrivate), mAcidSignKey.priv_exponent, fnd::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kAcidBase[nameidx], kRsaKeyModulus), mAcidSignKey.modulus, fnd::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kPkg2Base[nameidx], kRsaKeyPrivate), mPkg2SignKey.priv_exponent, fnd::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kPkg2Base[nameidx], kRsaKeyModulus), mPkg2SignKey.modulus, fnd::rsa::kRsa2048Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kPkiRootBase[nameidx], kRsaKeyPrivate), pki_root_sign_key.priv_exponent, fnd::rsa::kRsa4096Size);
_SAVE_KEYDATA(_CONCAT_2_STRINGS(kPkiRootBase[nameidx], kRsaKeyModulus), pki_root_sign_key.modulus, fnd::rsa::kRsa4096Size);
}
#undef _SAVE_KEYDATA
#undef _CONCAT_3_STRINGS
#undef _CONCAT_2_STRINGS
// Derive keys
for (size_t i = 0; i < kMasterKeyNum; i++)
{
if (master_key[i] != kNullAesKey)
{
if (aes_kek_generation_source != kNullAesKey && aes_key_generation_source != kNullAesKey)
{
if (i == 0 && nca_header_kek_source != kNullAesKey && nca_header_key_source != kNullAesXtsKey)
{
if (mNcaHeaderKey == kNullAesXtsKey)
{
fnd::aes::sAes128Key nca_header_kek;
nn::hac::AesKeygen::generateKey(nca_header_kek.key, aes_kek_generation_source.key, nca_header_kek_source.key, aes_key_generation_source.key, master_key[i].key);
nn::hac::AesKeygen::generateKey(mNcaHeaderKey.key[0], nca_header_key_source.key[0], nca_header_kek.key);
nn::hac::AesKeygen::generateKey(mNcaHeaderKey.key[1], nca_header_key_source.key[1], nca_header_kek.key);
}
}
for (size_t j = 0; j < nn::hac::nca::kKeyAreaEncryptionKeyNum; j++)
{
if (key_area_key_source[j] != kNullAesKey && mNcaKeyAreaEncryptionKey[j][i] == kNullAesKey)
{
nn::hac::AesKeygen::generateKey(mNcaKeyAreaEncryptionKey[j][i].key, aes_kek_generation_source.key, key_area_key_source[j].key, aes_key_generation_source.key, master_key[i].key);
}
}
}
if (ticket_titlekek_source != kNullAesKey && mETicketCommonKey[i] == kNullAesKey)
{
nn::hac::AesKeygen::generateKey(mETicketCommonKey[i].key, ticket_titlekek_source.key, master_key[i].key);
}
if (package2_key_source != kNullAesKey && mPkg2Key[i] == kNullAesKey)
{
nn::hac::AesKeygen::generateKey(mPkg2Key[i].key, package2_key_source.key, master_key[i].key);
}
}
}
// populate pki root keys
if (pki_root_sign_key != kNullRsa4096Key)
{
sPkiRootKey tmp;
tmp.name = nn::pki::sign::kRootIssuerStr;
tmp.key_type = nn::pki::sign::SIGN_ALGO_RSA4096;
tmp.rsa4096_key = pki_root_sign_key;
mPkiRootKeyList.addElement(tmp);
}
}
void KeyConfiguration::clearGeneralKeyConfiguration()
{
mAcidSignKey = kNullRsa2048Key;
mPkg2SignKey = kNullRsa2048Key;
mNcaHeader0SignKey = kNullRsa2048Key;
mXciHeaderSignKey = kNullRsa2048Key;
mPkiRootKeyList.clear();
mNcaHeaderKey = kNullAesXtsKey;
mXciHeaderKey = kNullAesKey;
for (size_t i = 0; i < kMasterKeyNum; i++)
{
mPkg1Key[i] = kNullAesKey;
mPkg2Key[i] = kNullAesKey;
mETicketCommonKey[i] = kNullAesKey;
for (size_t j = 0; j < kNcaKeakNum; j++)
{
mNcaKeyAreaEncryptionKey[j][i] = kNullAesKey;
mNcaKeyAreaEncryptionKey[j][i] = kNullAesKey;
}
}
}
void KeyConfiguration::clearNcaExternalKeys()
{
mNcaExternalContentKeyList.clear();
}
bool KeyConfiguration::getNcaHeaderKey(fnd::aes::sAesXts128Key& key) const
{
return copyOutKeyResourceIfExists(mNcaHeaderKey, key, kNullAesXtsKey);
}
bool KeyConfiguration::getNcaHeader0SignKey(fnd::rsa::sRsa2048Key& key) const
{
return copyOutKeyResourceIfExists(mNcaHeader0SignKey, key, kNullRsa2048Key);
}
bool KeyConfiguration::getAcidSignKey(fnd::rsa::sRsa2048Key& key) const
{
return copyOutKeyResourceIfExists(mAcidSignKey, key, kNullRsa2048Key);
}
bool KeyConfiguration::getNcaKeyAreaEncryptionKey(byte_t masterkey_index, byte_t keak_type, fnd::aes::sAes128Key& key) const
{
if (keak_type >= kNcaKeakNum || masterkey_index >= kMasterKeyNum)
{
return false;
}
return copyOutKeyResourceIfExists(mNcaKeyAreaEncryptionKey[keak_type][masterkey_index], key, kNullAesKey);
}
bool KeyConfiguration::getNcaKeyAreaEncryptionKeyHw(byte_t masterkey_index, byte_t keak_type, fnd::aes::sAes128Key& key) const
{
if (keak_type >= kNcaKeakNum || masterkey_index >= kMasterKeyNum)
{
return false;
}
return copyOutKeyResourceIfExists(mNcaKeyAreaEncryptionKeyHw[keak_type][masterkey_index], key, kNullAesKey);
}
void KeyConfiguration::addNcaExternalContentKey(const byte_t rights_id[nn::hac::nca::kRightsIdLen], const fnd::aes::sAes128Key& key)
{
sNcaExternalContentKey tmp;
memcpy(tmp.rights_id.data, rights_id, nn::hac::nca::kRightsIdLen);
tmp.key = key;
if (mNcaExternalContentKeyList.hasElement(tmp))
return;
mNcaExternalContentKeyList.addElement(tmp);
}
bool KeyConfiguration::getNcaExternalContentKey(const byte_t rights_id[nn::hac::nca::kRightsIdLen], fnd::aes::sAes128Key& key) const
{
sRightsId id;
bool res_exists = false;
memcpy(id.data, rights_id, nn::hac::nca::kRightsIdLen);
for (size_t i = 0; i < mNcaExternalContentKeyList.size(); i++)
{
if (mNcaExternalContentKeyList[i].rights_id == id)
{
res_exists = true;
key = mNcaExternalContentKeyList[i].key;
break;
}
}
return res_exists;
}
bool KeyConfiguration::getPkg1Key(byte_t masterkey_index, fnd::aes::sAes128Key& key) const
{
if (masterkey_index >= kMasterKeyNum)
{
return false;
}
return copyOutKeyResourceIfExists(mPkg1Key[masterkey_index], key, kNullAesKey);
}
bool KeyConfiguration::getPkg2Key(byte_t masterkey_index, fnd::aes::sAes128Key& key) const
{
if (masterkey_index >= kMasterKeyNum)
{
return false;
}
return copyOutKeyResourceIfExists(mPkg2Key[masterkey_index], key, kNullAesKey);
}
bool KeyConfiguration::getPkg2SignKey(fnd::rsa::sRsa2048Key& key) const
{
return copyOutKeyResourceIfExists(mPkg2SignKey, key, kNullRsa2048Key);
}
bool KeyConfiguration::getXciHeaderSignKey(fnd::rsa::sRsa2048Key& key) const
{
return copyOutKeyResourceIfExists(mXciHeaderSignKey, key, kNullRsa2048Key);
}
bool KeyConfiguration::getXciHeaderKey(fnd::aes::sAes128Key& key) const
{
return copyOutKeyResourceIfExists(mXciHeaderKey, key, kNullAesKey);
}
bool KeyConfiguration::getETicketCommonKey(byte_t masterkey_index, fnd::aes::sAes128Key& key) const
{
if (masterkey_index >= kMasterKeyNum)
{
return false;
}
return copyOutKeyResourceIfExists(mETicketCommonKey[masterkey_index], key, kNullAesKey);
}
bool KeyConfiguration::getPkiRootSignKey(const std::string& root_name, fnd::rsa::sRsa4096Key& key) const
{
bool res_exists = false;
for (size_t i = 0; i < mPkiRootKeyList.size(); i++)
{
if (root_name == mPkiRootKeyList[i].name && mPkiRootKeyList[i].key_type == nn::pki::sign::SIGN_ALGO_RSA4096)
{
res_exists = true;
key = mPkiRootKeyList[i].rsa4096_key;
break;
}
}
return res_exists;
}
bool KeyConfiguration::getPkiRootSignKey(const std::string& root_name, fnd::rsa::sRsa2048Key& key) const
{
bool res_exists = false;
for (size_t i = 0; i < mPkiRootKeyList.size(); i++)
{
if (root_name == mPkiRootKeyList[i].name && mPkiRootKeyList[i].key_type == nn::pki::sign::SIGN_ALGO_RSA2048)
{
res_exists = true;
key = mPkiRootKeyList[i].rsa2048_key;
break;
}
}
return res_exists;
}
bool KeyConfiguration::getPkiRootSignKey(const std::string& root_name, fnd::ecdsa::sEcdsa240Key& key) const
{
bool res_exists = false;
for (size_t i = 0; i < mPkiRootKeyList.size(); i++)
{
if (root_name == mPkiRootKeyList[i].name && mPkiRootKeyList[i].key_type == nn::pki::sign::SIGN_ALGO_ECDSA240)
{
res_exists = true;
key = mPkiRootKeyList[i].ecdsa240_key;
break;
}
}
return res_exists;
}

View file

@ -0,0 +1,206 @@
#pragma once
#include <string>
#include <cstring>
#include <fnd/types.h>
#include <fnd/aes.h>
#include <fnd/rsa.h>
#include <fnd/ecdsa.h>
#include <nn/hac/nca.h>
#include <nn/pki/SignedData.h>
#include <nn/es/TicketBody_V2.h>
class KeyConfiguration
{
public:
KeyConfiguration();
void importHactoolGenericKeyfile(const std::string& path);
//void importHactoolTitleKeyfile(const std::string& path);
void clearGeneralKeyConfiguration();
void clearNcaExternalKeys();
// nca keys
bool getNcaHeaderKey(fnd::aes::sAesXts128Key& key) const;
bool getNcaHeader0SignKey(fnd::rsa::sRsa2048Key& key) const;
bool getAcidSignKey(fnd::rsa::sRsa2048Key& key) const;
bool getNcaKeyAreaEncryptionKey(byte_t masterkey_index, byte_t keak_type, fnd::aes::sAes128Key& key) const;
bool getNcaKeyAreaEncryptionKeyHw(byte_t masterkey_index, byte_t keak_type, fnd::aes::sAes128Key& key) const;
// external content keys
void addNcaExternalContentKey(const byte_t rights_id[nn::hac::nca::kRightsIdLen], const fnd::aes::sAes128Key& key);
bool getNcaExternalContentKey(const byte_t rights_id[nn::hac::nca::kRightsIdLen], fnd::aes::sAes128Key& key) const;
// pkg1/pkg2
bool getPkg1Key(byte_t masterkey_index, fnd::aes::sAes128Key& key) const;
bool getPkg2Key(byte_t masterkey_index, fnd::aes::sAes128Key& key) const;
bool getPkg2SignKey(fnd::rsa::sRsa2048Key& key) const;
// xci keys
bool getXciHeaderSignKey(fnd::rsa::sRsa2048Key& key) const;
bool getXciHeaderKey(fnd::aes::sAes128Key& key) const;
// ticket
bool getETicketCommonKey(byte_t masterkey_index, fnd::aes::sAes128Key& key) const;
// pki
bool getPkiRootSignKey(const std::string& root_name, fnd::rsa::sRsa4096Key& key) const;
bool getPkiRootSignKey(const std::string& root_name, fnd::rsa::sRsa2048Key& key) const;
bool getPkiRootSignKey(const std::string& root_name, fnd::ecdsa::sEcdsa240Key& key) const;
private:
const std::string kModuleName = "KeyConfiguration";
const fnd::aes::sAes128Key kNullAesKey = {{0}};
const fnd::aes::sAesXts128Key kNullAesXtsKey = {{{0}}};
const fnd::rsa::sRsa4096Key kNullRsa4096Key = {{0}, {0}, {0}};
const fnd::rsa::sRsa2048Key kNullRsa2048Key = {{0}, {0}, {0}};
static const size_t kMasterKeyNum = 0x20;
static const size_t kNcaKeakNum = nn::hac::nca::kKeyAreaEncryptionKeyNum;
// keynames
enum NameVariantIndex
{
NNTOOLS,
LEGACY_HACTOOL,
LEGACY_0
};
static const size_t kNameVariantNum = 3;
const std::string kMasterBase[kNameVariantNum] = { "master", "master", "master" };
const std::string kPkg1Base[kNameVariantNum] = { "package1", "package1", "package1" };
const std::string kPkg2Base[kNameVariantNum] = { "package2", "package2", "package2" };
const std::string kXciHeaderBase[kNameVariantNum] = { "xci_header", "xci_header", "xci_header" };
const std::string kNcaHeaderBase[kNameVariantNum] = { "nca_header", "header", "nca_header" };
const std::string kAcidBase[kNameVariantNum] = { "acid", "acid", "acid" };
const std::string kPkiRootBase[kNameVariantNum] = { "pki_root", "pki_root", "pki_root" };
const std::string kTicketCommonKeyBase[kNameVariantNum] = { "ticket_commonkey", "titlekek", "ticket_commonkey" };
const std::string kNcaKeyAreaEncKeyBase[kNameVariantNum] = { "nca_body_keak", "key_area_key", "nca_body_keak" };
const std::string kNcaKeyAreaEncKeyHwBase[kNameVariantNum] = { "nca_body_keakhw", "key_area_hw_key", "nca_body_keakhw" };
const std::string kKekGenBase[kNameVariantNum] = { "aes_kek_generation", "aes_kek_generation", "aes_kek_generation" };
const std::string kKeyGenBase[kNameVariantNum] = { "aes_key_generation", "aes_key_generation", "aes_key_generation" };
// misc str
const std::string kKeyStr = "key";
const std::string kKekStr = "kek";
const std::string kSourceStr = "source";
const std::string kRsaKeyModulus = "sign_key_modulus";
const std::string kRsaKeyPrivate = "sign_key_private";
const std::string kNcaKeyAreaKeyIndexStr[kNcaKeakNum] = { "application", "ocean", "system" };
const std::string kKeyIndex[kMasterKeyNum] = {"00","01","02","03","04","05","06","07","08","09","0a","0b","0c","0d","0e","0f","10","11","12","13","14","15","16","17","18","19","1a","1b","1c","1d","1e","1f"};
struct sRightsId
{
byte_t data[nn::hac::nca::kRightsIdLen];
void operator=(const sRightsId& other)
{
memcpy(this->data, other.data, nn::hac::nca::kRightsIdLen);
}
bool operator==(const sRightsId& other) const
{
return memcmp(this->data, other.data, nn::hac::nca::kRightsIdLen) == 0;
}
bool operator!=(const sRightsId& other) const
{
return !(operator==(other));
}
};
struct sNcaExternalContentKey
{
sRightsId rights_id;
fnd::aes::sAes128Key key;
void operator=(const sNcaExternalContentKey& other)
{
rights_id = other.rights_id;
key = other.key;
}
bool operator==(const sNcaExternalContentKey& other) const
{
return (rights_id == other.rights_id) \
&& (key == other.key);
}
bool operator!=(const sNcaExternalContentKey& other) const
{
return !(operator==(other));
}
};
struct sPkiRootKey
{
std::string name;
nn::pki::sign::SignatureAlgo key_type;
fnd::rsa::sRsa4096Key rsa4096_key;
fnd::rsa::sRsa2048Key rsa2048_key;
fnd::ecdsa::sEcdsa240Key ecdsa240_key;
void operator=(const sPkiRootKey& other)
{
name = other.name;
key_type = other.key_type;
rsa4096_key = other.rsa4096_key;
rsa2048_key = other.rsa2048_key;
ecdsa240_key = other.ecdsa240_key;
}
bool operator==(const sPkiRootKey& other) const
{
return (name == other.name) \
&& (key_type == other.key_type) \
&& (rsa4096_key == other.rsa4096_key) \
&& (rsa2048_key == other.rsa2048_key) \
&& (ecdsa240_key == other.ecdsa240_key);
}
bool operator!=(const sPkiRootKey& other) const
{
return !(operator==(other));
}
};
/* general key config */
// acid
fnd::rsa::sRsa2048Key mAcidSignKey;
// pkg1 and pkg2
fnd::aes::sAes128Key mPkg1Key[kMasterKeyNum];
fnd::rsa::sRsa2048Key mPkg2SignKey;
fnd::aes::sAes128Key mPkg2Key[kMasterKeyNum];
// nca
fnd::rsa::sRsa2048Key mNcaHeader0SignKey;
fnd::aes::sAesXts128Key mNcaHeaderKey;
fnd::aes::sAes128Key mNcaKeyAreaEncryptionKey[kNcaKeakNum][kMasterKeyNum];
fnd::aes::sAes128Key mNcaKeyAreaEncryptionKeyHw[kNcaKeakNum][kMasterKeyNum];
// xci
fnd::rsa::sRsa2048Key mXciHeaderSignKey;
fnd::aes::sAes128Key mXciHeaderKey;
// ticket
fnd::aes::sAes128Key mETicketCommonKey[kMasterKeyNum];
// pki
fnd::List<sPkiRootKey> mPkiRootKeyList;
/* Nca External Keys */
fnd::List<sNcaExternalContentKey> mNcaExternalContentKeyList;
template <class T>
bool copyOutKeyResourceIfExists(const T& src, T& dst, const T& null_sample) const
{
bool resource_exists = false;
if (src != null_sample)
{
resource_exists = true;
dst = src;
}
return resource_exists;
}
};