key_manager: Add support for loading keys from partition data
This commit is contained in:
parent
d041d6231c
commit
4aad010f7a
|
@ -870,6 +870,92 @@ void KeyManager::SetKeyWrapped(S256KeyType id, Key256 key, u64 field1, u64 field
|
||||||
SetKey(id, key, field1, field2);
|
SetKey(id, key, field1, field2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KeyManager::PopulateFromPartitionData(PartitionDataManager data) {
|
||||||
|
if (!BaseDeriveNecessary())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!data.HasBoot0())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 0x20; ++i) {
|
||||||
|
if (encrypted_keyblobs[i] != std::array<u8, 0xB0>{})
|
||||||
|
continue;
|
||||||
|
encrypted_keyblobs[i] = data.GetEncryptedKeyblob(i);
|
||||||
|
WriteKeyToFile<0xB0>(KeyCategory::Console, fmt::format("encrypted_keyblob_{:02X}", i),
|
||||||
|
encrypted_keyblobs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetKeyWrapped(S128KeyType::Source, data.GetPackage2KeySource(),
|
||||||
|
static_cast<u64>(SourceKeyType::Package2));
|
||||||
|
SetKeyWrapped(S128KeyType::Source, data.GetAESKekGenerationSource(),
|
||||||
|
static_cast<u64>(SourceKeyType::AESKekGeneration));
|
||||||
|
SetKeyWrapped(S128KeyType::Source, data.GetTitlekekSource(),
|
||||||
|
static_cast<u64>(SourceKeyType::Titlekek));
|
||||||
|
SetKeyWrapped(S128KeyType::Source, data.GetMasterKeySource(),
|
||||||
|
static_cast<u64>(SourceKeyType::Master));
|
||||||
|
SetKeyWrapped(S128KeyType::Source, data.GetKeyblobMACKeySource(),
|
||||||
|
static_cast<u64>(SourceKeyType::KeyblobMAC));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < PartitionDataManager::MAX_KEYBLOB_SOURCE_HASH; ++i) {
|
||||||
|
SetKeyWrapped(S128KeyType::Source, data.GetKeyblobKeySource(i),
|
||||||
|
static_cast<u64>(SourceKeyType::Keyblob), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.HasFuses())
|
||||||
|
SetKeyWrapped(S128KeyType::SecureBoot, data.GetSecureBootKey());
|
||||||
|
|
||||||
|
DeriveBase();
|
||||||
|
|
||||||
|
Key128 latest_master{};
|
||||||
|
for (s8 i = 0x1F; i > 0; --i) {
|
||||||
|
if (GetKey(S128KeyType::Master, i) != Key128{}) {
|
||||||
|
latest_master = GetKey(S128KeyType::Master, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto masters = data.GetTZMasterKeys(latest_master);
|
||||||
|
for (size_t i = 0; i < 0x20; ++i) {
|
||||||
|
if (masters[i] != Key128{} && !HasKey(S128KeyType::Master, i))
|
||||||
|
SetKey(S128KeyType::Master, masters[i], i);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeriveBase();
|
||||||
|
|
||||||
|
if (!data.HasPackage2())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::array<Key128, 0x20> package2_keys{};
|
||||||
|
for (size_t i = 0; i < 0x20; ++i) {
|
||||||
|
if (HasKey(S128KeyType::Package2, i))
|
||||||
|
package2_keys[i] = GetKey(S128KeyType::Package2, i);
|
||||||
|
}
|
||||||
|
data.DecryptPackage2(package2_keys, Package2Type::NormalMain);
|
||||||
|
|
||||||
|
SetKeyWrapped(S128KeyType::Source, data.GetKeyAreaKeyApplicationSource(),
|
||||||
|
static_cast<u64>(SourceKeyType::KeyAreaKey),
|
||||||
|
static_cast<u64>(KeyAreaKeyType::Application));
|
||||||
|
SetKeyWrapped(S128KeyType::Source, data.GetKeyAreaKeyOceanSource(),
|
||||||
|
static_cast<u64>(SourceKeyType::KeyAreaKey),
|
||||||
|
static_cast<u64>(KeyAreaKeyType::Ocean));
|
||||||
|
SetKeyWrapped(S128KeyType::Source, data.GetKeyAreaKeySystemSource(),
|
||||||
|
static_cast<u64>(SourceKeyType::KeyAreaKey),
|
||||||
|
static_cast<u64>(KeyAreaKeyType::System));
|
||||||
|
SetKeyWrapped(S128KeyType::Source, data.GetSDKekSource(),
|
||||||
|
static_cast<u64>(SourceKeyType::SDKek));
|
||||||
|
SetKeyWrapped(S256KeyType::SDKeySource, data.GetSDSaveKeySource(),
|
||||||
|
static_cast<u64>(SDKeyType::Save));
|
||||||
|
SetKeyWrapped(S256KeyType::SDKeySource, data.GetSDNCAKeySource(),
|
||||||
|
static_cast<u64>(SDKeyType::NCA));
|
||||||
|
SetKeyWrapped(S128KeyType::Source, data.GetHeaderKekSource(),
|
||||||
|
static_cast<u64>(SourceKeyType::HeaderKek));
|
||||||
|
SetKeyWrapped(S256KeyType::HeaderSource, data.GetHeaderKeySource());
|
||||||
|
SetKeyWrapped(S128KeyType::Source, data.GetAESKeyGenerationSource(),
|
||||||
|
static_cast<u64>(SourceKeyType::AESKeyGeneration));
|
||||||
|
|
||||||
|
DeriveBase();
|
||||||
|
}
|
||||||
|
|
||||||
const boost::container::flat_map<std::string, KeyIndex<S128KeyType>> KeyManager::s128_file_id = {
|
const boost::container::flat_map<std::string, KeyIndex<S128KeyType>> KeyManager::s128_file_id = {
|
||||||
{"eticket_rsa_kek", {S128KeyType::ETicketRSAKek, 0, 0}},
|
{"eticket_rsa_kek", {S128KeyType::ETicketRSAKek, 0, 0}},
|
||||||
{"eticket_rsa_kek_source",
|
{"eticket_rsa_kek_source",
|
||||||
|
|
|
@ -158,6 +158,8 @@ public:
|
||||||
void DeriveBase();
|
void DeriveBase();
|
||||||
void DeriveETicket(PartitionDataManager data);
|
void DeriveETicket(PartitionDataManager data);
|
||||||
|
|
||||||
|
void PopulateFromPartitionData(PartitionDataManager data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<KeyIndex<S128KeyType>, Key128> s128_keys;
|
std::map<KeyIndex<S128KeyType>, Key128> s128_keys;
|
||||||
std::map<KeyIndex<S256KeyType>, Key256> s256_keys;
|
std::map<KeyIndex<S256KeyType>, Key256> s256_keys;
|
||||||
|
|
Reference in New Issue